/*
 * Copyright (C) 2016 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "LinkIconCollector.h"

#include "Document.h"
#include "ElementChildIterator.h"
#include "HTMLHeadElement.h"
#include "HTMLLinkElement.h"
#include "LinkIconType.h"
#include <wtf/text/StringToIntegerConversion.h>

namespace WebCore {

const unsigned defaultTouchIconWidth = 60;

static unsigned iconSize(const LinkIcon& icon)
{
    if (icon.size)
        return *icon.size;

    if (icon.type == LinkIconType::TouchIcon || icon.type == LinkIconType::TouchPrecomposedIcon)
        return defaultTouchIconWidth;

    return 0;
}

static int compareIcons(const LinkIcon& a, const LinkIcon& b)
{
    // Apple Touch icons always come first.
    if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
        return 1;
    if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
        return -1;

    unsigned aSize = iconSize(a);
    unsigned bSize = iconSize(b);

    if (bSize > aSize)
        return 1;
    if (bSize < aSize)
        return -1;

    // A Precomposed icon should come first if both icons have the same size.
    if (a.type != LinkIconType::TouchPrecomposedIcon && b.type == LinkIconType::TouchPrecomposedIcon)
        return 1;
    if (b.type != LinkIconType::TouchPrecomposedIcon && a.type == LinkIconType::TouchPrecomposedIcon)
        return -1;

    return 0;
}

auto LinkIconCollector::iconsOfTypes(OptionSet<LinkIconType> iconTypes) -> Vector<LinkIcon>
{
    RefPtr head = m_document.head();
    if (!head)
        return { };

    Vector<LinkIcon> icons;

    for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
        if (!linkElement.iconType())
            continue;

        auto iconType = *linkElement.iconType();
        if (!iconTypes.contains(iconType))
            continue;

        auto url = linkElement.href();
        if (!url.protocolIsInHTTPFamily())
            continue;

        // This icon size parsing is a little wonky - it only parses the first
        // part of the size, "60x70" becomes "60". This is for compatibility reasons
        // and is probably good enough for now.
        std::optional<unsigned> iconSize;
        if (linkElement.sizes().length())
            iconSize = parseIntegerAllowingTrailingJunk<unsigned>(linkElement.sizes().item(0));

        Vector<std::pair<String, String>> attributes;
        if (linkElement.hasAttributes()) {
            attributes.reserveCapacity(linkElement.attributeCount());
            for (const Attribute& attribute : linkElement.attributesIterator())
                attributes.uncheckedAppend({ attribute.localName(), attribute.value() });
        }

        icons.append({ url, iconType, linkElement.type(), iconSize, WTFMove(attributes) });
    }

    std::sort(icons.begin(), icons.end(), [](auto& a, auto& b) {
        return compareIcons(a, b) < 0;
    });

    return icons;
}

}
