// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/uri.h"

#include "vm/zone.h"

namespace dart {

static bool IsUnreservedChar(intptr_t value) {
  return ((value >= 'a' && value <= 'z') || (value >= 'A' && value <= 'Z') ||
          (value >= '0' && value <= '9') || value == '-' || value == '.' ||
          value == '_' || value == '~');
}

static bool IsDelimiter(intptr_t value) {
  switch (value) {
    case ':':
    case '/':
    case '?':
    case '#':
    case '[':
    case ']':
    case '@':
    case '!':
    case '$':
    case '&':
    case '\'':
    case '(':
    case ')':
    case '*':
    case '+':
    case ',':
    case ';':
    case '=':
      return true;
    default:
      return false;
  }
}

static bool IsHexDigit(char value) {
  return ((value >= '0' && value <= '9') || (value >= 'A' && value <= 'F') ||
          (value >= 'a' && value <= 'f'));
}

static int HexValue(char digit) {
  if ((digit >= '0' && digit <= '9')) {
    return digit - '0';
  }
  if ((digit >= 'A' && digit <= 'F')) {
    return digit - 'A' + 10;
  }
  if ((digit >= 'a' && digit <= 'f')) {
    return digit - 'a' + 10;
  }
  UNREACHABLE();
  return 0;
}

static int GetEscapedValue(const char* str, intptr_t pos, intptr_t len) {
  if (pos + 2 >= len) {
    // Not enough room for a valid escape sequence.
    return -1;
  }
  if (str[pos] != '%') {
    // Escape sequences start with '%'.
    return -1;
  }

  char digit1 = str[pos + 1];
  char digit2 = str[pos + 2];
  if (!IsHexDigit(digit1) || !IsHexDigit(digit2)) {
    // Invalid escape sequence.  Ignore it.
    return -1;
  }
  return HexValue(digit1) * 16 + HexValue(digit2);
}

static char* NormalizeEscapes(const char* str, intptr_t len) {
  // Allocate the buffer.
  Zone* zone = ThreadState::Current()->zone();
  // We multiply len by three because a percent-escape sequence is
  // three characters long (e.g. ' ' -> '%20).  +1 for '\0'.  We could
  // take two passes through the string and avoid the excess
  // allocation, but it's zone-memory so it doesn't seem necessary.
  char* buffer = zone->Alloc<char>(len * 3 + 1);

  // Copy the string, normalizing as we go.
  intptr_t buffer_pos = 0;
  intptr_t pos = 0;
  while (pos < len) {
    int escaped_value = GetEscapedValue(str, pos, len);
    if (escaped_value >= 0) {
      // If one of the special "unreserved" characters has been
      // escaped, revert the escaping.  Otherwise preserve the
      // escaping.
      if (IsUnreservedChar(escaped_value)) {
        buffer[buffer_pos] = escaped_value;
        buffer_pos++;
      } else {
        Utils::SNPrint(buffer + buffer_pos, 4, "%%%02X", escaped_value);
        buffer_pos += 3;
      }
      pos += 3;
    } else {
      char c = str[pos];
      // If a delimiter or unreserved character is currently not
      // escaped, preserve that.  If there is a busted %-sequence in
      // the input, preserve that too.
      if (c == '%' || IsDelimiter(c) || IsUnreservedChar(c)) {
        buffer[buffer_pos] = c;
        buffer_pos++;
      } else {
        // Escape funky characters.
        Utils::SNPrint(buffer + buffer_pos, 4, "%%%02X", c);
        buffer_pos += 3;
      }
      pos++;
    }
  }
  buffer[buffer_pos] = '\0';
  return buffer;
}

// Lower-case a string in place.
static void StringLower(char* str) {
  const intptr_t len = strlen(str);
  intptr_t i = 0;
  while (i < len) {
    int escaped_value = GetEscapedValue(str, i, len);
    if (escaped_value >= 0) {
      // Don't lowercase escape sequences.
      i += 3;
    } else {
      // I don't use tolower() because I don't want the locale
      // transforming any non-acii characters.
      char c = str[i];
      if (c >= 'A' && c <= 'Z') {
        str[i] = c + ('a' - 'A');
      }
      i++;
    }
  }
}

static void ClearParsedUri(ParsedUri* parsed_uri) {
  parsed_uri->scheme = NULL;
  parsed_uri->userinfo = NULL;
  parsed_uri->host = NULL;
  parsed_uri->port = NULL;
  parsed_uri->path = NULL;
  parsed_uri->query = NULL;
  parsed_uri->fragment = NULL;
}

static intptr_t ParseAuthority(const char* authority, ParsedUri* parsed_uri) {
  Zone* zone = ThreadState::Current()->zone();
  const char* current = authority;
  intptr_t len = 0;

  size_t userinfo_len = strcspn(current, "@/");
  if (current[userinfo_len] == '@') {
    // The '@' character follows the optional userinfo string.
    parsed_uri->userinfo = NormalizeEscapes(current, userinfo_len);
    current += userinfo_len + 1;
    len += userinfo_len + 1;
  } else {
    parsed_uri->userinfo = NULL;
  }

  size_t host_len = strcspn(current, ":/");
  char* host = NormalizeEscapes(current, host_len);
  StringLower(host);
  parsed_uri->host = host;
  len += host_len;

  if (current[host_len] == ':') {
    // The ':' character precedes the optional port string.
    const char* port_start = current + host_len + 1;  // +1 for ':'
    size_t port_len = strcspn(port_start, "/");
    parsed_uri->port = zone->MakeCopyOfStringN(port_start, port_len);
    len += 1 + port_len;  // +1 for ':'
  } else {
    parsed_uri->port = NULL;
  }
  return len;
}

// Performs a simple parse of a uri into its components.
// See RFC 3986 Section 3: Syntax.
bool ParseUri(const char* uri, ParsedUri* parsed_uri) {
  Zone* zone = ThreadState::Current()->zone();

  // The first ':' separates the scheme from the rest of the uri.  If
  // a ':' occurs after the first '/' it doesn't count.
  size_t scheme_len = strcspn(uri, ":/");
  const char* rest = uri;
  if (uri[scheme_len] == ':') {
    char* scheme = zone->MakeCopyOfStringN(uri, scheme_len);
    StringLower(scheme);
    parsed_uri->scheme = scheme;
    rest = uri + scheme_len + 1;
  } else {
    parsed_uri->scheme = NULL;
  }

  // The first '#' separates the optional fragment
  const char* hash_pos = rest + strcspn(rest, "#");
  if (*hash_pos == '#') {
    // There is a fragment part.
    const char* fragment_start = hash_pos + 1;
    parsed_uri->fragment =
        NormalizeEscapes(fragment_start, strlen(fragment_start));
  } else {
    parsed_uri->fragment = NULL;
  }

  // The first '?' or '#' separates the hierarchical part from the
  // optional query.
  const char* question_pos = rest + strcspn(rest, "?#");
  if (*question_pos == '?') {
    // There is a query part.
    const char* query_start = question_pos + 1;
    parsed_uri->query = NormalizeEscapes(query_start, (hash_pos - query_start));
  } else {
    parsed_uri->query = NULL;
  }

  const char* path_start = rest;
  if (rest[0] == '/' && rest[1] == '/') {
    // There is an authority part.
    const char* authority_start = rest + 2;  // 2 for '//'.

    intptr_t authority_len = ParseAuthority(authority_start, parsed_uri);
    if (authority_len < 0) {
      ClearParsedUri(parsed_uri);
      return false;
    }
    path_start = authority_start + authority_len;
  } else {
    parsed_uri->userinfo = NULL;
    parsed_uri->host = NULL;
    parsed_uri->port = NULL;
  }

  // The path is the substring between the authority and the query.
  parsed_uri->path = NormalizeEscapes(path_start, (question_pos - path_start));
  return true;
}

static char* RemoveLastSegment(char* current, char* base) {
  if (current == base) {
    return current;
  }
  ASSERT(current > base);
  for (current--; current > base; current--) {
    if (*current == '/') {
      // We have found the beginning of the last segment.
      return current;
    }
  }
  ASSERT(current == base);
  return current;
}

static intptr_t SegmentLength(const char* input) {
  const char* cp = input;

  // Include initial slash in the segment, if any.
  if (*cp == '/') {
    cp++;
  }

  // Don't include trailing slash in the segment.
  cp += strcspn(cp, "/");
  return cp - input;
}

// See RFC 3986 Section 5.2.4: Remove Dot Segments.
static const char* RemoveDotSegments(const char* path) {
  const char* input = path;

  // The output path will always be less than or equal to the size of
  // the input path.
  Zone* zone = ThreadState::Current()->zone();
  char* buffer = zone->Alloc<char>(strlen(path) + 1);  // +1 for '\0'
  char* output = buffer;

  while (*input != '\0') {
    if (strncmp("../", input, 3) == 0) {
      // Discard initial "../" from the input.  It's junk.
      input += 3;

    } else if (strncmp("./", input, 3) == 0) {
      // Discard initial "./" from the input.  It's junk.
      input += 2;

    } else if (strncmp("/./", input, 3) == 0) {
      // Advance past the "/." part of the input.
      input += 2;

    } else if (strcmp("/.", input) == 0) {
      // Pretend the input just contains a "/".
      input = "/";

    } else if (strncmp("/../", input, 4) == 0) {
      // Advance past the "/.." part of the input and remove one
      // segment from the output.
      input += 3;
      output = RemoveLastSegment(output, buffer);

    } else if (strcmp("/..", input) == 0) {
      // Pretend the input contains a "/" and remove one segment from
      // the output.
      input = "/";
      output = RemoveLastSegment(output, buffer);

    } else if (strcmp("..", input) == 0) {
      // The input has been reduced to nothing useful.
      input += 2;

    } else if (strcmp(".", input) == 0) {
      // The input has been reduced to nothing useful.
      input += 1;

    } else {
      intptr_t segment_len = SegmentLength(input);
      if (input[0] != '/' && output != buffer) {
        *output = '/';
        output++;
      }
      strncpy(output, input, segment_len);
      output += segment_len;
      input += segment_len;
    }
  }
  *output = '\0';
  return buffer;
}

// See RFC 3986 Section 5.2.3: Merge Paths.
static const char* MergePaths(const char* base_path, const char* ref_path) {
  Zone* zone = ThreadState::Current()->zone();
  if (base_path[0] == '\0') {
    // If the base_path is empty, we prepend '/'.
    return zone->PrintToString("/%s", ref_path);
  }

  // We need to find the last '/' in base_path.
  const char* last_slash = strrchr(base_path, '/');
  if (last_slash == NULL) {
    // There is no slash in the base_path.  Return the ref_path unchanged.
    return ref_path;
  }

  // We found a '/' in the base_path.  Cut off everything after it and
  // add the ref_path.
  intptr_t truncated_base_len = last_slash - base_path;
  intptr_t ref_path_len = strlen(ref_path);
  intptr_t len = truncated_base_len + ref_path_len + 1;  // +1 for '/'
  char* buffer = zone->Alloc<char>(len + 1);             // +1 for '\0'

  // Copy truncated base.
  strncpy(buffer, base_path, truncated_base_len);

  // Add a slash.
  buffer[truncated_base_len] = '/';

  // Copy the ref_path.
  strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len + 1);

  return buffer;
}

static char* BuildUri(const ParsedUri& uri) {
  Zone* zone = ThreadState::Current()->zone();
  ASSERT(uri.path != NULL);

  const char* fragment = uri.fragment == NULL ? "" : uri.fragment;
  const char* fragment_separator = uri.fragment == NULL ? "" : "#";
  const char* query = uri.query == NULL ? "" : uri.query;
  const char* query_separator = uri.query == NULL ? "" : "?";

  // If there is no scheme for this uri, just build a relative uri of
  // the form: "path[?query][#fragment]".  This occurs when we resolve
  // relative urls inside a "dart:" library.
  if (uri.scheme == NULL) {
    ASSERT(uri.userinfo == NULL && uri.host == NULL && uri.port == NULL);
    return zone->PrintToString("%s%s%s%s%s", uri.path, query_separator, query,
                               fragment_separator, fragment);
  }

  // Uri with no authority: "scheme:path[?query][#fragment]"
  if (uri.host == NULL) {
    ASSERT(uri.userinfo == NULL && uri.port == NULL);
    return zone->PrintToString("%s:%s%s%s%s%s", uri.scheme, uri.path,
                               query_separator, query, fragment_separator,
                               fragment);
  }

  const char* user = uri.userinfo == NULL ? "" : uri.userinfo;
  const char* user_separator = uri.userinfo == NULL ? "" : "@";
  const char* port = uri.port == NULL ? "" : uri.port;
  const char* port_separator = uri.port == NULL ? "" : ":";

  // If the path doesn't start with a '/', add one.  We need it to
  // separate the path from the authority.
  const char* path_separator =
      ((uri.path[0] == '\0' || uri.path[0] == '/') ? "" : "/");

  // Uri with authority:
  //   "scheme://[userinfo@]host[:port][/]path[?query][#fragment]"
  return zone->PrintToString(
      "%s://%s%s%s%s%s%s%s%s%s%s%s",  // There is *nothing* wrong with this.
      uri.scheme, user, user_separator, uri.host, port_separator, port,
      path_separator, uri.path, query_separator, query, fragment_separator,
      fragment);
}

// See RFC 3986 Section 5: Reference Resolution
bool ResolveUri(const char* ref_uri,
                const char* base_uri,
                const char** target_uri) {
  // Parse the reference uri.
  ParsedUri ref;
  if (!ParseUri(ref_uri, &ref)) {
    *target_uri = NULL;
    return false;
  }

  ParsedUri target;
  if (ref.scheme != NULL) {
    if (strcmp(ref.scheme, "dart") == 0) {
      Zone* zone = ThreadState::Current()->zone();
      *target_uri = zone->MakeCopyOfString(ref_uri);
      return true;
    }

    // When the ref_uri specifies a scheme, the base_uri is ignored.
    target.scheme = ref.scheme;
    target.userinfo = ref.userinfo;
    target.host = ref.host;
    target.port = ref.port;
    target.path = RemoveDotSegments(ref.path);
    target.query = ref.query;
    target.fragment = ref.fragment;
    *target_uri = BuildUri(target);
    return true;
  }

  // Parse the base uri.
  ParsedUri base;
  if (!ParseUri(base_uri, &base)) {
    *target_uri = NULL;
    return false;
  }

  if ((base.scheme != NULL) && strcmp(base.scheme, "dart") == 0) {
    Zone* zone = ThreadState::Current()->zone();
    *target_uri = zone->MakeCopyOfString(ref_uri);
    return true;
  }

  if (ref.host != NULL) {
    // When the ref_uri specifies an authority, we only use the base scheme.
    target.scheme = base.scheme;
    target.userinfo = ref.userinfo;
    target.host = ref.host;
    target.port = ref.port;
    target.path = RemoveDotSegments(ref.path);
    target.query = ref.query;
    target.fragment = ref.fragment;
    *target_uri = BuildUri(target);
    return true;
  }

  if (ref.path[0] == '\0') {
    // Empty path.  Use most parts of base_uri.
    target.scheme = base.scheme;
    target.userinfo = base.userinfo;
    target.host = base.host;
    target.port = base.port;
    target.path = base.path;
    target.query = ((ref.query == NULL) ? base.query : ref.query);
    target.fragment = ref.fragment;
    *target_uri = BuildUri(target);
    return true;

  } else if (ref.path[0] == '/') {
    // Absolute path.  ref_path wins.
    target.scheme = base.scheme;
    target.userinfo = base.userinfo;
    target.host = base.host;
    target.port = base.port;
    target.path = RemoveDotSegments(ref.path);
    target.query = ref.query;
    target.fragment = ref.fragment;
    *target_uri = BuildUri(target);
    return true;

  } else {
    // Relative path.  We need to merge the base path and the ref path.

    if (base.scheme == NULL && base.host == NULL && base.path[0] != '/') {
      // The dart:core Uri class handles resolving a relative uri
      // against a second relative uri specially, in a way not
      // described in the RFC.  We do not need to support this for
      // library resolution.  If we need to implement this later, we
      // can.
      *target_uri = NULL;
      return false;
    }

    target.scheme = base.scheme;
    target.userinfo = base.userinfo;
    target.host = base.host;
    target.port = base.port;
    target.path = RemoveDotSegments(MergePaths(base.path, ref.path));
    target.query = ref.query;
    target.fragment = ref.fragment;
    *target_uri = BuildUri(target);
    return true;
  }
}

}  // namespace dart
