/*
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "AccessibilityTableCell.h"

#include "AXObjectCache.h"
#include "AccessibilityTable.h"
#include "AccessibilityTableRow.h"
#include "ElementIterator.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "RenderObject.h"
#include "RenderTableCell.h"

namespace WebCore {
    
using namespace HTMLNames;

AccessibilityTableCell::AccessibilityTableCell(RenderObject* renderer)
    : AccessibilityRenderObject(renderer)
    , m_axColIndexFromRow(-1)
{
}

AccessibilityTableCell::~AccessibilityTableCell() = default;

Ref<AccessibilityTableCell> AccessibilityTableCell::create(RenderObject* renderer)
{
    return adoptRef(*new AccessibilityTableCell(renderer));
}

bool AccessibilityTableCell::computeAccessibilityIsIgnored() const
{
    AccessibilityObjectInclusion decision = defaultObjectInclusion();
    if (decision == AccessibilityObjectInclusion::IncludeObject)
        return false;
    if (decision == AccessibilityObjectInclusion::IgnoreObject)
        return true;
    
    // Ignore anonymous table cells as long as they're not in a table (ie. when display:table is used).
    RenderObject* renderTable = is<RenderTableCell>(renderer()) ? downcast<RenderTableCell>(*m_renderer).table() : nullptr;
    bool inTable = renderTable && renderTable->node() && (renderTable->node()->hasTagName(tableTag) || nodeHasRole(renderTable->node(), "grid"));
    if (!node() && !inTable)
        return true;
        
    if (!isTableCell())
        return AccessibilityRenderObject::computeAccessibilityIsIgnored();
    
    return false;
}

AccessibilityTable* AccessibilityTableCell::parentTable() const
{
    if (!is<RenderTableCell>(renderer()))
        return nullptr;

    // If the document no longer exists, we might not have an axObjectCache.
    if (!axObjectCache())
        return nullptr;
    
    // Do not use getOrCreate. parentTable() can be called while the render tree is being modified 
    // by javascript, and creating a table element may try to access the render tree while in a bad state.
    // By using only get() implies that the AXTable must be created before AXTableCells. This should
    // always be the case when AT clients access a table.
    // https://bugs.webkit.org/show_bug.cgi?id=42652
    AccessibilityObject* parentTable = axObjectCache()->get(downcast<RenderTableCell>(*m_renderer).table());
    if (!is<AccessibilityTable>(parentTable))
        return nullptr;
    
    // The RenderTableCell's table() object might be anonymous sometimes. We should handle it gracefully
    // by finding the right table.
    if (!parentTable->node()) {
        for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
            // If this is a non-anonymous table object, but not an accessibility table, we should stop because
            // we don't want to choose another ancestor table as this cell's table.
            if (is<AccessibilityTable>(*parent)) {
                auto& parentTable = downcast<AccessibilityTable>(*parent);
                if (parentTable.isExposable())
                    return &parentTable;
                if (parentTable.node())
                    break;
            }
        }
        return nullptr;
    }
    
    return downcast<AccessibilityTable>(parentTable);
}
    
bool AccessibilityTableCell::isTableCell() const
{
    // If the parent table is an accessibility table, then we are a table cell.
    // This used to check if the unignoredParent was a row, but that exploded performance if
    // this was in nested tables. This check should be just as good.
    AccessibilityObject* parentTable = this->parentTable();
    return is<AccessibilityTable>(parentTable) && downcast<AccessibilityTable>(*parentTable).isExposable();
}
    
AccessibilityRole AccessibilityTableCell::determineAccessibilityRole()
{
    // AccessibilityRenderObject::determineAccessibleRole provides any ARIA-supplied
    // role, falling back on the role to be used if we determine here that the element
    // should not be exposed as a cell. Thus if we already know it's a cell, return that.
    AccessibilityRole defaultRole = AccessibilityRenderObject::determineAccessibilityRole();
    if (defaultRole == AccessibilityRole::ColumnHeader || defaultRole == AccessibilityRole::RowHeader || defaultRole == AccessibilityRole::Cell || defaultRole == AccessibilityRole::GridCell)
        return defaultRole;

    if (!isTableCell())
        return defaultRole;
    if (isColumnHeaderCell())
        return AccessibilityRole::ColumnHeader;
    if (isRowHeaderCell())
        return AccessibilityRole::RowHeader;

    return AccessibilityRole::Cell;
}
    
bool AccessibilityTableCell::isTableHeaderCell() const
{
    return node() && node()->hasTagName(thTag);
}

bool AccessibilityTableCell::isColumnHeaderCell() const
{
    const AtomString& scope = getAttribute(scopeAttr);
    if (scope == "col" || scope == "colgroup")
        return true;
    if (scope == "row" || scope == "rowgroup")
        return false;
    if (!isTableHeaderCell())
        return false;

    // We are in a situation after checking the scope attribute.
    // It is an attempt to resolve the type of th element without support in the specification.
    // Checking tableTag and tbodyTag allows to check the case of direct row placement in the table and lets stop the loop at the table level.
    for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
        if (parentNode->hasTagName(theadTag))
            return true;
        if (parentNode->hasTagName(tfootTag))
            return false;
        if (parentNode->hasTagName(tableTag) || parentNode->hasTagName(tbodyTag)) {
            auto rowRange = rowIndexRange();
            if (!rowRange.first)
                return true;
            return false;
        }
    }
    return false;
}

bool AccessibilityTableCell::isRowHeaderCell() const
{
    const AtomString& scope = getAttribute(scopeAttr);
    if (scope == "row" || scope == "rowgroup")
        return true;
    if (scope == "col" || scope == "colgroup")
        return false;
    if (!isTableHeaderCell())
        return false;

    // We are in a situation after checking the scope attribute.
    // It is an attempt to resolve the type of th element without support in the specification.
    // Checking tableTag allows to check the case of direct row placement in the table and lets stop the loop at the table level.
    for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
        if (parentNode->hasTagName(tfootTag) || parentNode->hasTagName(tbodyTag) || parentNode->hasTagName(tableTag)) {
            auto colRange = columnIndexRange();
            if (!colRange.first)
                return true;
            return false;
        }
        if (parentNode->hasTagName(theadTag))
            return false;
    }
    return false;
}

bool AccessibilityTableCell::isTableCellInSameRowGroup(AXCoreObject* otherTableCell)
{
    Node* parentNode = node();
    for ( ; parentNode; parentNode = parentNode->parentNode()) {
        if (parentNode->hasTagName(theadTag) || parentNode->hasTagName(tbodyTag) || parentNode->hasTagName(tfootTag))
            break;
    }
    
    Node* otherParentNode = otherTableCell->node();
    for ( ; otherParentNode; otherParentNode = otherParentNode->parentNode()) {
        if (otherParentNode->hasTagName(theadTag) || otherParentNode->hasTagName(tbodyTag) || otherParentNode->hasTagName(tfootTag))
            break;
    }
    
    return otherParentNode == parentNode;
}

bool AccessibilityTableCell::isTableCellInSameColGroup(AXCoreObject* tableCell)
{
    auto colRange = columnIndexRange();
    auto otherColRange = tableCell->columnIndexRange();

    if (colRange.first <= (otherColRange.first + otherColRange.second))
        return true;
    return false;
}
    
String AccessibilityTableCell::expandedTextValue() const
{
    return getAttribute(abbrAttr);
}
    
bool AccessibilityTableCell::supportsExpandedTextValue() const
{
    return isTableHeaderCell() && hasAttribute(abbrAttr);
}
    
AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::columnHeaders()
{
    AccessibilityChildrenVector headers;
    AccessibilityTable* parent = parentTable();
    if (!parent)
        return headers;

    // Choose columnHeaders as the place where the "headers" attribute is reported.
    ariaElementsFromAttribute(headers, headersAttr);
    // If the headers attribute returned valid values, then do not further search for column headers.
    if (!headers.isEmpty())
        return headers;

    auto rowRange = rowIndexRange();
    auto colRange = columnIndexRange();

    for (unsigned row = 0; row < rowRange.first; row++) {
        auto* tableCell = parent->cellForColumnAndRow(colRange.first, row);
        if (!tableCell || tableCell == this || headers.contains(tableCell))
            continue;

        ASSERT(is<AccessibilityObject>(tableCell));
        const AtomString& scope = downcast<AccessibilityObject>(tableCell)->getAttribute(scopeAttr);
        if (scope == "colgroup" && isTableCellInSameColGroup(tableCell))
            headers.append(tableCell);
        else if (tableCell->isColumnHeaderCell())
            headers.append(tableCell);
    }

    return headers;
}
    
AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::rowHeaders()
{
    AccessibilityChildrenVector headers;
    AccessibilityTable* parent = parentTable();
    if (!parent)
        return headers;

    auto rowRange = rowIndexRange();
    auto colRange = columnIndexRange();

    for (unsigned column = 0; column < colRange.first; column++) {
        auto* tableCell = parent->cellForColumnAndRow(column, rowRange.first);
        if (!tableCell || tableCell == this || headers.contains(tableCell))
            continue;
        
        const AtomString& scope = downcast<AccessibilityObject>(tableCell)->getAttribute(scopeAttr);
        if (scope == "rowgroup" && isTableCellInSameRowGroup(tableCell))
            headers.append(tableCell);
        else if (tableCell->isRowHeaderCell())
            headers.append(tableCell);
    }

    return headers;
}

AccessibilityTableRow* AccessibilityTableCell::ariaOwnedByParent() const
{
    AccessibilityChildrenVector ariaOwnedBy;
    ariaOwnsReferencingElements(ariaOwnedBy);
    if (ariaOwnedBy.size() == 1 && ariaOwnedBy[0]->isTableRow())
        return downcast<AccessibilityTableRow>(ariaOwnedBy[0].get());

    return nullptr;
}

AXCoreObject* AccessibilityTableCell::parentObjectUnignored() const
{
    if (auto ownerParent = ariaOwnedByParent())
        return ownerParent;
    return AccessibilityRenderObject::parentObjectUnignored();
}

AccessibilityTableRow* AccessibilityTableCell::parentRow() const
{
    if (auto ownerParent = ariaOwnedByParent())
        return ownerParent;
    
    AXCoreObject* parent = parentObjectUnignored();
    if (!is<AccessibilityTableRow>(*parent))
        return nullptr;
    return downcast<AccessibilityTableRow>(parent);
}

std::pair<unsigned, unsigned> AccessibilityTableCell::rowIndexRange() const
{
    std::pair<unsigned, unsigned> rowRange { 0, 1 };
    if (!is<RenderTableCell>(renderer()))
        return rowRange;

    RenderTableCell& renderCell = downcast<RenderTableCell>(*m_renderer);

    // ARIA 1.1's aria-rowspan attribute is intended for cells and gridcells which are not contained
    // in a native table. But if we have a valid author-provided value and do not have an explicit
    // native host language value for the rowspan, expose the ARIA value.
    rowRange.second = axRowSpan();
    if (static_cast<int>(rowRange.second) == -1)
        rowRange.second = renderCell.rowSpan();
    
    if (AccessibilityTableRow* parentRow = this->parentRow())
        rowRange.first = parentRow->rowIndex();

    return rowRange;
}
    
std::pair<unsigned, unsigned> AccessibilityTableCell::columnIndexRange() const
{
    std::pair<unsigned, unsigned> columnRange { 0, 1 };
    if (!is<RenderTableCell>(renderer()))
        return columnRange;

    const RenderTableCell& cell = downcast<RenderTableCell>(*m_renderer);
    columnRange.first = cell.table()->colToEffCol(cell.col());

    // ARIA 1.1's aria-colspan attribute is intended for cells and gridcells which are not contained
    // in a native table. But if we have a valid author-provided value and do not have an explicit
    // native host language value for the colspan, expose the ARIA value.
    columnRange.second = axColumnSpan();
    if (static_cast<int>(columnRange.second) != -1)
        return columnRange;

    columnRange.second = cell.table()->colToEffCol(cell.col() + cell.colSpan()) - columnRange.first;

    return columnRange;
}
    
AccessibilityObject* AccessibilityTableCell::titleUIElement() const
{
    // Try to find if the first cell in this row is a <th>. If it is,
    // then it can act as the title ui element. (This is only in the
    // case when the table is not appearing as an AXTable.)
    if (isTableCell() || !is<RenderTableCell>(renderer()))
        return nullptr;

    // Table cells that are th cannot have title ui elements, since by definition
    // they are title ui elements
    Node* node = m_renderer->node();
    if (node && node->hasTagName(thTag))
        return nullptr;
    
    RenderTableCell& renderCell = downcast<RenderTableCell>(*m_renderer);

    // If this cell is in the first column, there is no need to continue.
    int col = renderCell.col();
    if (!col)
        return nullptr;

    int row = renderCell.rowIndex();

    RenderTableSection* section = renderCell.section();
    if (!section)
        return nullptr;
    
    RenderTableCell* headerCell = section->primaryCellAt(row, 0);
    if (!headerCell || headerCell == &renderCell)
        return nullptr;

    if (!headerCell->element() || !headerCell->element()->hasTagName(thTag))
        return nullptr;
    
    return axObjectCache()->getOrCreate(headerCell);
}
    
int AccessibilityTableCell::axColumnIndex() const
{
    if (int value = getIntegralAttribute(aria_colindexAttr); value >= 1)
        return value;

    // "ARIA 1.1: If the set of columns which is present in the DOM is contiguous, and if there are no cells which span more than one row
    // or column in that set, then authors may place aria-colindex on each row, setting the value to the index of the first column of the set."
    // Here, we let its parent row to set its index beforehand, so we don't have to go through the siblings to calculate the index.
    AccessibilityTableRow* parentRow = this->parentRow();
    if (parentRow && m_axColIndexFromRow != -1)
        return m_axColIndexFromRow;
    
    return -1;
}
    
int AccessibilityTableCell::axRowIndex() const
{
    // ARIA 1.1: Authors should place aria-rowindex on each row. Authors may also place
    // aria-rowindex on all of the children or owned elements of each row.
    if (int value = getIntegralAttribute(aria_rowindexAttr); value >= 1)
        return value;

    if (AccessibilityTableRow* parentRow = this->parentRow())
        return parentRow->axRowIndex();

    return -1;
}

int AccessibilityTableCell::axColumnSpan() const
{
    // According to the ARIA spec, "If aria-colpan is used on an element for which the host language
    // provides an equivalent attribute, user agents must ignore the value of aria-colspan."
    if (hasAttribute(colspanAttr))
        return -1;

    // ARIA 1.1: Authors must set the value of aria-colspan to an integer greater than or equal to 1.
    if (int value = getIntegralAttribute(aria_colspanAttr); value >= 1)
        return value;

    return -1;
}

int AccessibilityTableCell::axRowSpan() const
{
    // According to the ARIA spec, "If aria-rowspan is used on an element for which the host language
    // provides an equivalent attribute, user agents must ignore the value of aria-rowspan."
    if (hasAttribute(rowspanAttr))
        return -1;

    // ARIA 1.1: Authors must set the value of aria-rowspan to an integer greater than or equal to 0.
    // Setting the value to 0 indicates that the cell or gridcell is to span all the remaining rows in the row group.
    if (getAttribute(aria_rowspanAttr) == "0")
        return 0;
    if (int value = getIntegralAttribute(aria_rowspanAttr); value >= 1)
        return value;

    return -1;
}
    
} // namespace WebCore
