// 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.

// Canonicalizer functions for working with and resolving relative URLs.

#include <iostream>

#include "src/lib/fxl/logging.h"
#include "src/lib/url/url_canon.h"
#include "src/lib/url/url_canon_internal.h"
#include "src/lib/url/url_constants.h"
#include "src/lib/url/url_file.h"
#include "src/lib/url/url_parse_internal.h"
#include "src/lib/url/url_util_internal.h"

namespace url {

namespace {

// Firefox does a case-sensitive compare (which is probably wrong--Mozilla bug
// 379034), whereas IE is case-insensitive.
//
// We choose to be more permissive like IE. We don't need to worry about
// unescaping or anything here: neither IE or Firefox allow this. We also
// don't have to worry about invalid scheme characters since we are comparing
// against the canonical scheme of the base.
//
// The base URL should always be canonical, therefore it should be ASCII.
bool AreSchemesEqual(const char* base, const Component& base_scheme, const char* cmp,
                     const Component& cmp_scheme) {
  if (base_scheme.len() != cmp_scheme.len())
    return false;
  for (size_t i = 0; i < base_scheme.len(); i++) {
    // We assume the base is already canonical, so we don't have to
    // canonicalize it.
    if (CanonicalSchemeChar(cmp[cmp_scheme.begin + i]) != base[base_scheme.begin + i])
      return false;
  }
  return true;
}

// Copies all characters in the range [begin, end) of |spec| to the output,
// up until and including the last slash. There should be a slash in the
// range, if not, nothing will be copied.
//
// For stardard URLs the input should be canonical, but when resolving relative
// URLs on a non-standard base (like "data:") the input can be anything.
void CopyToLastSlash(const char* spec, int begin, int end, CanonOutput* output) {
  // Find the last slash.
  int last_slash = -1;
  for (int i = end - 1; i >= begin; i--) {
    if (spec[i] == '/' || spec[i] == '\\') {
      last_slash = i;
      break;
    }
  }
  if (last_slash < 0)
    return;  // No slash.

  // Copy.
  for (int i = begin; i <= last_slash; i++)
    output->push_back(spec[i]);
}

// Copies a single component from the source to the output. This is used
// when resolving relative URLs and a given component is unchanged. Since the
// source should already be canonical, we don't have to do anything special,
// and the input is ASCII.
void CopyOneComponent(const char* source, const Component& source_component, CanonOutput* output,
                      Component* output_component) {
  if (!source_component.is_valid()) {
    // This component is not present.
    *output_component = Component();
    return;
  }

  output_component->begin = output->length();
  int source_end = source_component.end();
  for (int i = source_component.begin; i < source_end; i++)
    output->push_back(source[i]);
  output_component->set_len(output->length() - output_component->begin);
}

// A subroutine of DoResolveRelativeURL, this resolves the URL knowning that
// the input is a relative path or less (qyuery or ref).
bool DoResolveRelativePath(const char* base_url, const Parsed& base_parsed, bool base_is_file,
                           const char* relative_url, const Component& relative_component,
                           CharsetConverter* query_converter, CanonOutput* output,
                           Parsed* out_parsed) {
  bool success = true;

  // We know the authority section didn't change, copy it to the output. We
  // also know we have a path so can copy up to there.
  Component path, query, ref;
  ParsePathInternal(relative_url, relative_component, &path, &query, &ref);
  // Canonical URLs always have a path, so we can use that offset.
  output->Append(base_url, base_parsed.path.begin);

  if (path.is_nonempty()) {
    // The path is replaced or modified.
    int true_path_begin = output->length();
    int base_path_begin = base_parsed.path.begin;

    if (IsURLSlash(relative_url[path.begin])) {
      // Easy case: the path is an absolute path on the server, so we can
      // just replace everything from the path on with the new versions.
      // Since the input should be canonical hierarchical URL, we should
      // always have a path.
      success &= CanonicalizePath(relative_url, path, output, &out_parsed->path);
    } else {
      // Relative path, replace the query, and reference. We take the
      // original path with the file part stripped, and append the new path.
      // The canonicalizer will take care of resolving ".." and "."
      int path_begin = output->length();
      CopyToLastSlash(base_url, base_path_begin, base_parsed.path.end(), output);
      success &= CanonicalizePartialPath(relative_url, path, path_begin, output);
      out_parsed->path = MakeRange(path_begin, output->length());

      // Copy the rest of the stuff after the path from the relative path.
    }

    // Finish with the query and reference part (these can't fail).
    CanonicalizeQuery(relative_url, query, query_converter, output, &out_parsed->query);
    CanonicalizeRef(relative_url, ref, output, &out_parsed->ref);

    // Fix the path beginning to add back the "C:" we may have written above.
    out_parsed->path = MakeRange(true_path_begin, out_parsed->path.end());
    return success;
  }

  // If we get here, the path is unchanged: copy to output.
  CopyOneComponent(base_url, base_parsed.path, output, &out_parsed->path);

  if (query.is_valid()) {
    // Just the query specified, replace the query and reference (ignore
    // failures for refs)
    CanonicalizeQuery(relative_url, query, query_converter, output, &out_parsed->query);
    CanonicalizeRef(relative_url, ref, output, &out_parsed->ref);
    return success;
  }

  // If we get here, the query is unchanged: copy to output. Note that the
  // range of the query parameter doesn't include the question mark, so we
  // have to add it manually if there is a component.
  if (base_parsed.query.is_valid())
    output->push_back('?');
  CopyOneComponent(base_url, base_parsed.query, output, &out_parsed->query);

  if (ref.is_valid()) {
    // Just the reference specified: replace it (ignoring failures).
    CanonicalizeRef(relative_url, ref, output, &out_parsed->ref);
    return success;
  }

  // We should always have something to do in this function, the caller checks
  // that some component is being replaced.
  FX_DCHECK(false) << "Not reached";
  return success;
}

// Resolves a relative URL that happens to be an absolute file path. Examples
// include: "//hostname/path", "/c:/foo", and "//hostname/c:/foo".
bool DoResolveAbsoluteFile(const char* relative_url, const Component& relative_component,
                           CharsetConverter* query_converter, CanonOutput* output,
                           Parsed* out_parsed) {
  // Parse the file URL. The file URl parsing function uses the same logic
  // as we do for determining if the file is absolute, in which case it will
  // not bother to look for a scheme.
  Parsed relative_parsed;
  ParseFileURL(&relative_url[relative_component.begin], relative_component.len(), &relative_parsed);

  return CanonicalizeFileURL(&relative_url[relative_component.begin], relative_component.len(),
                             relative_parsed, query_converter, output, out_parsed);
}

}  // namespace

// See IsRelativeURL in the header file for usage.
bool IsRelativeURL(const char* base, const Parsed& base_parsed, const char* url, size_t url_len,
                   bool is_base_hierarchical, bool* is_relative, Component* relative_component) {
  *is_relative = false;  // So we can default later to not relative.

  // Trim whitespace and construct a new range for the substring.
  size_t begin = 0;
  TrimURL(url, &begin, &url_len);
  if (begin >= url_len) {
    // Empty URLs are relative, but do nothing.
    *relative_component = Component(begin, 0);
    *is_relative = true;
    return true;
  }

  // See if we've got a scheme, if not, we know this is a relative URL.
  // BUT, just because we have a scheme, doesn't make it absolute.
  // "http:foo.html" is a relative URL with path "foo.html". If the scheme is
  // empty, we treat it as relative (":foo"), like IE does.
  Component scheme;
  const bool scheme_is_empty = !ExtractScheme(url, url_len, &scheme) || scheme.len() == 0;
  if (scheme_is_empty) {
    if (url[begin] == '#') {
      // |url| is a bare fragment (e.g. "#foo"). This can be resolved against
      // any base. Fall-through.
    } else if (!is_base_hierarchical) {
      // Don't allow relative URLs if the base scheme doesn't support it.
      return false;
    }

    *relative_component = MakeRange(begin, url_len);
    *is_relative = true;
    return true;
  }

  // If the scheme isn't valid, then it's relative.
  int scheme_end = scheme.end();
  for (int i = scheme.begin; i < scheme_end; i++) {
    if (!CanonicalSchemeChar(url[i])) {
      if (!is_base_hierarchical) {
        // Don't allow relative URLs if the base scheme doesn't support it.
        return false;
      }
      *relative_component = MakeRange(begin, url_len);
      *is_relative = true;
      return true;
    }
  }

  // If the scheme is not the same, then we can't count it as relative.
  if (!AreSchemesEqual(base, base_parsed.scheme, url, scheme))
    return true;

  // When the scheme that they both share is not hierarchical, treat the
  // incoming scheme as absolute (this way with the base of "data:foo",
  // "data:bar" will be reported as absolute.
  if (!is_base_hierarchical)
    return true;

  size_t colon_offset = scheme.end();

  // ExtractScheme guarantees that the colon immediately follows what it
  // considers to be the scheme. CountConsecutiveSlashes will handle the
  // case where the begin offset is the end of the input.
  size_t num_slashes = CountConsecutiveSlashes(url, colon_offset + 1, url_len);

  if (num_slashes == 0 || num_slashes == 1) {
    // No slashes means it's a relative path like "http:foo.html". One slash
    // is an absolute path. "http:/home/foo.html"
    *is_relative = true;
    *relative_component = MakeRange(colon_offset + 1, url_len);
    return true;
  }

  // Two or more slashes after the scheme we treat as absolute.
  return true;
}

// TODO(brettw) treat two slashes as root like Mozilla for FTP?
bool ResolveRelativeURL(const char* base_url, const Parsed& base_parsed, bool base_is_file,
                        const char* relative_url, const Component& relative_component,
                        CharsetConverter* query_converter, CanonOutput* output,
                        Parsed* out_parsed) {
  // Starting point for our output parsed. We'll fix what we change.
  *out_parsed = base_parsed;

  // Sanity check: the input should have a host or we'll break badly below.
  // We can only resolve relative URLs with base URLs that have hosts and
  // paths (even the default path of "/" is OK).
  //
  // We allow hosts with no length so we can handle file URLs, for example.
  if (base_parsed.path.is_invalid_or_empty()) {
    // On error, return the input (resolving a relative URL on a non-relative
    // base = the base).
    size_t base_len = base_parsed.Length();
    for (size_t i = 0; i < base_len; i++)
      output->push_back(base_url[i]);
    return false;
  }

  if (relative_component.is_invalid_or_empty()) {
    // Empty relative URL, leave unchanged, only removing the ref component.
    size_t base_len = base_parsed.Length();
    if (base_parsed.ref.is_valid()) {
      base_len -= base_parsed.ref.len() + 1;
    }
    out_parsed->ref.reset();
    output->Append(base_url, base_len);
    return true;
  }

  size_t num_slashes =
      CountConsecutiveSlashes(relative_url, relative_component.begin, relative_component.end());

  // Other platforms need explicit handling for file: URLs with multiple
  // slashes because the generic scheme parsing always extracts a host, but a
  // file: URL only has a host if it has exactly 2 slashes. Even if it does
  // have a host, we want to use the special host detection logic for file
  // URLs provided by DoResolveAbsoluteFile(), as opposed to the generic host
  // detection logic, for consistency with parsing file URLs from scratch.
  // This also handles the special case where the URL is only slashes,
  // since that doesn't have a host part either.
  if (base_is_file && (num_slashes >= 2 || num_slashes == relative_component.len())) {
    return DoResolveAbsoluteFile(relative_url, relative_component, query_converter, output,
                                 out_parsed);
  }

  // Any other double-slashes mean that this is relative to the scheme.
  if (num_slashes >= 2) {
    // Make & parse an url with base_url's scheme and everything else from
    // relative_url.
    std::string new_url;
    new_url.reserve(base_parsed.scheme.len() + 1 + relative_component.len());
    new_url.append(&base_url[base_parsed.scheme.begin], base_parsed.scheme.len());
    new_url.push_back(':');
    new_url.append(&relative_url[relative_component.begin], relative_component.len());
    Parsed new_parsed;
    ParseStandardURL(new_url.c_str(), new_url.size(), &new_parsed);

    // Canonicalize the combined url.
    return CanonicalizeStandardURL(new_url.c_str(), new_url.size(), new_parsed, query_converter,
                                   output, out_parsed);
  }

  // When we get here, we know that the relative URL is on the same host.
  return DoResolveRelativePath(base_url, base_parsed, base_is_file, relative_url,
                               relative_component, query_converter, output, out_parsed);
}

}  // namespace url
