/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "VisitedLinkState.h"

#include "ElementIterator.h"
#include "Frame.h"
#include "HTMLAnchorElement.h"
#include "Page.h"
#include "SVGAElement.h"
#include "SVGNames.h"
#include "VisitedLinkStore.h"
#include "XLinkNames.h"

namespace WebCore {

using namespace HTMLNames;

inline static const AtomString* linkAttribute(const Element& element)
{
    if (!element.isLink())
        return nullptr;
    if (element.isHTMLElement())
        return &element.attributeWithoutSynchronization(HTMLNames::hrefAttr);
    if (element.isSVGElement())
        return &element.getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr);
    return nullptr;
}

VisitedLinkState::VisitedLinkState(Document& document)
    : m_document(document)
{
}

void VisitedLinkState::invalidateStyleForAllLinks()
{
    if (m_linksCheckedForVisitedState.isEmpty())
        return;
    for (auto& element : descendantsOfType<Element>(m_document)) {
        if (element.isLink())
            element.invalidateStyleForSubtree();
    }
}

inline static Optional<SharedStringHash> linkHashForElement(const Element& element)
{
    if (is<HTMLAnchorElement>(element))
        return downcast<HTMLAnchorElement>(element).visitedLinkHash();
    if (is<SVGAElement>(element))
        return downcast<SVGAElement>(element).visitedLinkHash();
    return WTF::nullopt;
}

void VisitedLinkState::invalidateStyleForLink(SharedStringHash linkHash)
{
    if (!m_linksCheckedForVisitedState.contains(linkHash))
        return;
    for (auto& element : descendantsOfType<Element>(m_document)) {
        if (element.isLink() && linkHashForElement(element) == linkHash)
            element.invalidateStyleForSubtree();
    }
}

InsideLink VisitedLinkState::determineLinkStateSlowCase(const Element& element)
{
    ASSERT(element.isLink());

    const AtomString* attribute = linkAttribute(element);
    if (!attribute || attribute->isNull())
        return InsideLink::NotInside;

    auto hashIfFound = linkHashForElement(element);

    if (!hashIfFound)
        return attribute->isEmpty() ? InsideLink::InsideVisited : InsideLink::InsideUnvisited;

    auto hash = *hashIfFound;

    // An empty href (hash==0) refers to the document itself which is always visited. It is useful to check this explicitly so
    // that visited links can be tested in platform independent manner, without explicit support in the test harness.
    if (!hash)
        return InsideLink::InsideVisited;

    Frame* frame = element.document().frame();
    if (!frame)
        return InsideLink::InsideUnvisited;

    Page* page = frame->page();
    if (!page)
        return InsideLink::InsideUnvisited;

    m_linksCheckedForVisitedState.add(hash);

    if (!page->visitedLinkStore().isLinkVisited(*page, hash, element.document().baseURL(), *attribute))
        return InsideLink::InsideUnvisited;

    return InsideLink::InsideVisited;
}

} // namespace WebCore
