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

#include <string_view>

#include "polyfills/base/check.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_file.h"
#include "url/url_parse_internal.h"

// Interesting IE file:isms...
//
//  INPUT                      OUTPUT
//  =========================  ==============================
//  file:/foo/bar              file:///foo/bar
//      The result here seems totally invalid!?!? This isn't UNC.
//
//  file:/
//  file:// or any other number of slashes
//      IE6 doesn't do anything at all if you click on this link. No error:
//      nothing. IE6's history system seems to always color this link, so I'm
//      guessing that it maps internally to the empty URL.
//
//  C:\                        file:///C:/
//      When on a file: URL source page, this link will work. When over HTTP,
//      the file: URL will appear in the status bar but the link will not work
//      (security restriction for all file URLs).
//
//  file:foo/                  file:foo/     (invalid?!?!?)
//  file:/foo/                 file:///foo/  (invalid?!?!?)
//  file://foo/                file://foo/   (UNC to server "foo")
//  file:///foo/               file:///foo/  (invalid, seems to be a file)
//  file:////foo/              file://foo/   (UNC to server "foo")
//      Any more than four slashes is also treated as UNC.
//
//  file:C:/                   file://C:/
//  file:/C:/                  file://C:/
//      The number of slashes after "file:" don't matter if the thing following
//      it looks like an absolute drive path. Also, slashes and backslashes are
//      equally valid here.

namespace url {

namespace {

// Returns the index of the next slash in the input after the given index, or
// `spec.size()` if the end of the input is reached.
template <typename CharT>
size_t FindNextSlash(std::basic_string_view<CharT> spec, size_t begin_index) {
  size_t idx = begin_index;
  while (idx < spec.size() && !IsSlashOrBackslash(spec[idx])) {
    idx++;
  }
  return idx;
}

// A subcomponent of DoParseFileUrl, the input of this function should be a UNC
// path name, with the index of the first character after the slashes following
// the scheme given in `after_slashes`. This will initialize the host, path,
// query, and ref, and leave the other output components untouched
// (DoParseFileUrl handles these for us).
template <typename CharT>
void DoParseUnc(std::basic_string_view<CharT> url,
                size_t after_slashes,
                Parsed* parsed) {
  size_t url_len = url.size();
  // The cast is safe because `FindNextSlash` will never return anything longer
  // than `url_len`.
  size_t next_slash = FindNextSlash(url, after_slashes);

  // Everything up until that first slash we found (or end of string) is the
  // host name, which will end up being the UNC host. For example,
  // "file://foo/bar.txt" will get a server name of "foo" and a path of "/bar".
  // Later, on Windows, this should be treated as the filename "\\foo\bar.txt"
  // in proper UNC notation.
  if (after_slashes < next_slash) {
    parsed->host = MakeRange(after_slashes, next_slash);
  } else {
    parsed->host.reset();
  }
  if (next_slash < url_len) {
    ParsePathInternal(url.data(), MakeRange(next_slash, url_len), &parsed->path,
                      &parsed->query, &parsed->ref);
  } else {
    parsed->path.reset();
  }
}

// A subcomponent of DoParseFileUrl, the input should be a local file, with the
// beginning of the path indicated by the index in `path_begin`. This will
// initialize the host, path, query, and ref, and leave the other output
// components untouched (DoParseFileURL handles these for us).
template <typename CharT>
void DoParseLocalFile(std::basic_string_view<CharT> url,
                      size_t path_begin,
                      Parsed* parsed) {
  parsed->host.reset();
  ParsePathInternal(url.data(), MakeRange(path_begin, url.size()),
                    &parsed->path, &parsed->query, &parsed->ref);
}

// Backend for the external functions that operates on either char type.
// Handles cases where there is a scheme, but also when handed the first
// character following the "file:" at the beginning of the spec. If so,
// this is usually a slash, but needn't be; we allow paths like "file:c:\foo".
template <typename CharT>
Parsed DoParseFileUrl(std::basic_string_view<CharT> url) {
  // Strip leading & trailing spaces and control characters.
  auto [begin, end] = TrimUrl(url);
  url = url.substr(0, end);

  // Find the scheme, if any.
  size_t num_slashes = CountConsecutiveSlashesOrBackslashes(url, begin);
  size_t after_scheme;
  size_t after_slashes;
  Parsed parsed;
#ifdef WIN32
  // See how many slashes there are. We want to handle cases like UNC but also
  // "/c:/foo". This is when there is no scheme, so we can allow pages to do
  // links like "c:/foo/bar" or "//foo/bar". This is also called by the
  // relative URL resolver when it determines there is an absolute URL, which
  // may give us input like "/c:/foo".
  after_slashes = begin + num_slashes;
  if (DoesBeginWindowsDriveSpec(url.data(), after_slashes, url.length())) {
    // Windows path, don't try to extract the scheme (for example, "c:\foo").
    after_scheme = after_slashes;
  } else if (DoesBeginUNCPath(url.data(), begin, url.length(), false)) {
    // Windows UNC path: don't try to extract the scheme, but keep the slashes.
    after_scheme = begin;
  } else
#endif
  {
    // ExtractScheme doesn't understand the possibility of filenames with
    // colons in them, in which case it returns the entire spec up to the
    // colon as the scheme. So handle /foo.c:5 as a file but foo.c:5 as
    // the foo.c: scheme.
    if (!num_slashes && ExtractScheme(url.substr(begin), &parsed.scheme)) {
      // Offset the results since we gave ExtractScheme a substring.
      parsed.scheme.begin += begin;
      after_scheme = static_cast<size_t>(parsed.scheme.end() + 1);
    } else {
      // No scheme found, remember that.
      parsed.scheme.reset();
      after_scheme = begin;
    }
  }

  // Handle empty specs ones that contain only whitespace or control chars,
  // or that are just the scheme (for example "file:").
  if (after_scheme == url.length()) {
    return parsed;
  }

  num_slashes = CountConsecutiveSlashesOrBackslashes(url, after_scheme);
  after_slashes = after_scheme + num_slashes;
#ifdef WIN32
  // Check whether the input is a drive again. We checked above for windows
  // drive specs, but that's only at the very beginning to see if we have a
  // scheme at all. This test will be duplicated in that case, but will
  // additionally handle all cases with a real scheme such as "file:///C:/".
  if (!DoesBeginWindowsDriveSpec(url.data(), after_slashes, url.length()) &&
      num_slashes != 3) {
    // Anything not beginning with a drive spec ("c:\") on Windows is treated
    // as UNC, with the exception of three slashes which always means a file.
    // Even IE7 treats file:///foo/bar as "/foo/bar", which then fails.
    DoParseUnc(url, after_slashes, &parsed);
    return parsed;
  }
#else
  // file: URL with exactly 2 slashes is considered to have a host component.
  if (num_slashes == 2) {
    DoParseUnc(url, after_slashes, &parsed);
    return parsed;
  }
#endif  // WIN32

  // Easy and common case, the full path immediately follows the scheme
  // (modulo slashes), as in "file://c:/foo". Just treat everything from
  // there to the end as the path. Empty hosts have 0 length instead of -1.
  // We include the last slash as part of the path if there is one.
  DoParseLocalFile(
      url, num_slashes > 0 ? after_scheme + num_slashes - 1 : after_scheme,
      &parsed);
  return parsed;
}

}  // namespace

Parsed ParseFileUrl(std::string_view url) {
  return DoParseFileUrl(url);
}

Parsed ParseFileUrl(std::u16string_view url) {
  return DoParseFileUrl(url);
}

}  // namespace url
