// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser;

import android.text.TextUtils;

import org.chromium.base.CollectionUtil;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;

/**
 * Utilities for working with URIs (and URLs). These methods may be used in security-sensitive
 * contexts (after all, origins are the security boundary on the web), and so the correctness bar
 * must be high.
 */
public class UrlUtilities {
    /**
     * URI schemes that ContentView can handle.
     */
    private static final HashSet<String> ACCEPTED_SCHEMES = CollectionUtil.newHashSet(
        "about", "data", "file", "http", "https", "inline", "javascript");

    /**
     * URI schemes that Chrome can download.
     */
    private static final HashSet<String> DOWNLOADABLE_SCHEMES = CollectionUtil.newHashSet(
        "data", "filesystem", "http", "https");

    /**
     * @param uri A URI.
     *
     * @return True if the URI's scheme is one that ContentView can handle.
     */
    public static boolean isAcceptedScheme(URI uri) {
        return ACCEPTED_SCHEMES.contains(uri.getScheme());
    }

    /**
     * @param uri A URI.
     *
     * @return True if the URI's scheme is one that ContentView can handle.
     */
    public static boolean isAcceptedScheme(String uri) {
        try {
            return isAcceptedScheme(new URI(uri));
        } catch (URISyntaxException e) {
            return false;
        }
    }

    /**
     * @param uri A URI.
     *
     * @return True if the URI's scheme is one that Chrome can download.
     */
    public static boolean isDownloadableScheme(URI uri) {
        return DOWNLOADABLE_SCHEMES.contains(uri.getScheme());
    }

    /**
     * @param uri A URI.
     *
     * @return True if the URI's scheme is one that Chrome can download.
     */
    public static boolean isDownloadableScheme(String uri) {
        try {
            return isDownloadableScheme(new URI(uri));
        } catch (URISyntaxException e) {
            return false;
        }
    }

    /**
     * @param uri A URI to repair.
     *
     * @return A String representation of a URI that will be valid for loading in a ContentView.
     */
    public static String fixUrl(String uri) {
        if (uri == null) return null;

        try {
            String fixedUri = uri.trim();
            if (fixedUri.indexOf("://") == 0) {
                return "http" + fixedUri;
            }
            if (fixedUri.indexOf(":") == -1) {
                return "http://" + fixedUri;
            }

            URI parsed = new URI(fixedUri);
            if (parsed.getScheme() == null) {
                parsed = new URI(
                        "http",
                        null,  // userInfo
                        parsed.getHost(),
                        parsed.getPort(),
                        parsed.getRawPath(),
                        parsed.getRawQuery(),
                        parsed.getRawFragment());
            }
            return parsed.toString();
        } catch (URISyntaxException e) {
            // Can't do anything.
            return uri;
        }
    }

    /**
     * Builds a String that strips down the URL to the its scheme, host, and port.
     * @param uri URI to break down.
     * @return Stripped-down String containing the essential bits of the URL, or null if we fail
     *         to strip it down.
     */
    public static String getOriginForDisplay(URI uri) {
        String scheme = uri.getScheme();
        String host = uri.getHost();
        int port = uri.getPort();
        if (TextUtils.isEmpty(scheme) || TextUtils.isEmpty(host)) return null;

        if (port == -1 || (port == 80 && "http".equals(scheme))
                || (port == 443 && "https".equals(scheme))) {
            return scheme + "://" + host;
        } else {
            return scheme + "://" + host + ":" + port;
        }
    }

    /**
     * Determines whether or not the given URLs belong to the same broad domain or host.
     * "Broad domain" is defined as the TLD + 1 or the host.
     *
     * For example, the TLD + 1 for http://news.google.com would be "google.com" and would be shared
     * with other Google properties like http://finance.google.com.
     *
     * If {@code includePrivateRegistries} is marked as true, then private domain registries (like
     * appspot.com) are considered "effective TLDs" -- all subdomains of appspot.com would be
     * considered distinct (effective TLD = ".appspot.com" + 1).
     * This means that http://chromiumreview.appspot.com and http://example.appspot.com would not
     * belong to the same host.
     * If {@code includePrivateRegistries} is false, all subdomains of appspot.com
     * would be considered to be the same domain (TLD = ".com" + 1).
     *
     * @param primaryUrl First URL
     * @param secondaryUrl Second URL
     * @param includePrivateRegistries Whether or not to consider private registries.
     * @return True iff the two URIs belong to the same domain or host.
     */
    public static boolean sameDomainOrHost(String primaryUrl, String secondaryUrl,
            boolean includePrivateRegistries) {
        return nativeSameDomainOrHost(primaryUrl, secondaryUrl, includePrivateRegistries);
    }

    /**
     * This function works by calling net::registry_controlled_domains::GetDomainAndRegistry with
     * the filter EXCLUDE_PRIVATE_REGISTRIES.
     *
     * @param uri A URI
     *
     * @return The registered, organization-identifying host and all its registry information, but
     * no subdomains, from the given URI. Returns an empty string if the URI is invalid, has no host
     * (e.g. a file: URI), has multiple trailing dots, is an IP address, has only one subcomponent
     * (i.e. no dots other than leading/trailing ones), or is itself a recognized registry
     * identifier.
     *
     * TODO(rmcilroy): remove this method once all callers have been updated to use two parameter
     * version.
     */
    @Deprecated
    public static String getDomainAndRegistry(String uri) {
        return nativeGetDomainAndRegistry(uri, false);
    }

    /**
     * This function works by calling net::registry_controlled_domains::GetDomainAndRegistry
     *
     * @param uri A URI
     * @param includePrivateRegistries Whether or not to consider private registries.
     *
     * @return The registered, organization-identifying host and all its registry information, but
     * no subdomains, from the given URI. Returns an empty string if the URI is invalid, has no host
     * (e.g. a file: URI), has multiple trailing dots, is an IP address, has only one subcomponent
     * (i.e. no dots other than leading/trailing ones), or is itself a recognized registry
     * identifier.
     */
    public static String getDomainAndRegistry(String uri, boolean includePrivateRegistries) {
        return nativeGetDomainAndRegistry(uri, includePrivateRegistries);
    }

    private static native boolean nativeSameDomainOrHost(String primaryUrl, String secondaryUrl,
            boolean includePrivateRegistries);
    private static native String nativeGetDomainAndRegistry(String url,
            boolean includePrivateRegistries);
    public static native boolean nativeIsGoogleSearchUrl(String url);
}

@@ -5417,874 +5417,8 @@
  %7D%0A%0A
-    /**%0A     * This function works by calling net::registry_controlled_domains::GetDomainAndRegistry with%0A     * the filter EXCLUDE_PRIVATE_REGISTRIES.%0A     *%0A     * @param uri A URI%0A     *%0A     * @return The registered, organization-identifying host and all its registry information, but%0A     * no subdomains, from the given URI. Returns an empty string if the URI is invalid, has no host%0A     * (e.g. a file: URI), has multiple trailing dots, is an IP address, has only one subcomponent%0A     * (i.e. no dots other than leading/trailing ones), or is itself a recognized registry%0A     * identifier.%0A     *%0A     * TODO(rmcilroy): remove this method once all callers have been updated to use two parameter%0A     * version.%0A     */%0A    @Deprecated%0A    public static String getDomainAndRegistry(String uri) %7B%0A        return nativeGetDomainAndRegistry(uri, false);%0A    %7D%0A%0A
     

Remove deprecated method from UrlUtilities