// Copyright (c) 2013, 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.

import 'dart:math' as math;

import 'characters.dart' as chars;
import 'internal_style.dart';
import 'style.dart';
import 'parsed_path.dart';
import 'path_exception.dart';
import '../path.dart' as p;

Context createInternal() => Context._internal();

/// An instantiable class for manipulating paths. Unlike the top-level
/// functions, this lets you explicitly select what platform the paths will use.
class Context {
  /// Creates a new path context for the given style and current directory.
  ///
  /// If [style] is omitted, it uses the host operating system's path style. If
  /// only [current] is omitted, it defaults ".". If *both* [style] and
  /// [current] are omitted, [current] defaults to the real current working
  /// directory.
  ///
  /// On the browser, [style] defaults to [Style.url] and [current] defaults to
  /// the current URL.
  factory Context({Style style, String current}) {
    if (current == null) {
      if (style == null) {
        current = p.current;
      } else {
        current = ".";
      }
    }

    if (style == null) {
      style = Style.platform;
    } else if (style is! InternalStyle) {
      throw ArgumentError("Only styles defined by the path package are "
          "allowed.");
    }

    return Context._(style as InternalStyle, current);
  }

  /// Create a [Context] to be used internally within path.
  Context._internal()
      : style = Style.platform as InternalStyle,
        _current = null;

  Context._(this.style, this._current);

  /// The style of path that this context works with.
  final InternalStyle style;

  /// The current directory given when Context was created. If null, current
  /// directory is evaluated from 'p.current'.
  final String _current;

  /// The current directory that relative paths are relative to.
  String get current => _current != null ? _current : p.current;

  /// Gets the path separator for the context's [style]. On Mac and Linux,
  /// this is `/`. On Windows, it's `\`.
  String get separator => style.separator;

  /// Creates a new path by appending the given path parts to [current].
  /// Equivalent to [join()] with [current] as the first argument. Example:
  ///
  ///     var context = new Context(current: '/root');
  ///     context.absolute('path', 'to', 'foo'); // -> '/root/path/to/foo'
  ///
  /// If [current] isn't absolute, this won't return an absolute path.
  String absolute(String part1,
      [String part2,
      String part3,
      String part4,
      String part5,
      String part6,
      String part7]) {
    _validateArgList(
        "absolute", [part1, part2, part3, part4, part5, part6, part7]);

    // If there's a single absolute path, just return it. This is a lot faster
    // for the common case of `p.absolute(path)`.
    if (part2 == null && isAbsolute(part1) && !isRootRelative(part1)) {
      return part1;
    }

    return join(current, part1, part2, part3, part4, part5, part6, part7);
  }

  /// Gets the part of [path] after the last separator on the context's
  /// platform.
  ///
  ///     context.basename('path/to/foo.dart'); // -> 'foo.dart'
  ///     context.basename('path/to');          // -> 'to'
  ///
  /// Trailing separators are ignored.
  ///
  ///     context.basename('path/to/'); // -> 'to'
  String basename(String path) => _parse(path).basename;

  /// Gets the part of [path] after the last separator on the context's
  /// platform, and without any trailing file extension.
  ///
  ///     context.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
  ///
  /// Trailing separators are ignored.
  ///
  ///     context.basenameWithoutExtension('path/to/foo.dart/'); // -> 'foo'
  String basenameWithoutExtension(String path) =>
      _parse(path).basenameWithoutExtension;

  /// Gets the part of [path] before the last separator.
  ///
  ///     context.dirname('path/to/foo.dart'); // -> 'path/to'
  ///     context.dirname('path/to');          // -> 'path'
  ///
  /// Trailing separators are ignored.
  ///
  ///     context.dirname('path/to/'); // -> 'path'
  String dirname(String path) {
    var parsed = _parse(path);
    parsed.removeTrailingSeparators();
    if (parsed.parts.isEmpty) return parsed.root == null ? '.' : parsed.root;
    if (parsed.parts.length == 1) {
      return parsed.root == null ? '.' : parsed.root;
    }
    parsed.parts.removeLast();
    parsed.separators.removeLast();
    parsed.removeTrailingSeparators();
    return parsed.toString();
  }

  /// Gets the file extension of [path]: the portion of [basename] from the last
  /// `.` to the end (including the `.` itself).
  ///
  ///     context.extension('path/to/foo.dart'); // -> '.dart'
  ///     context.extension('path/to/foo'); // -> ''
  ///     context.extension('path.to/foo'); // -> ''
  ///     context.extension('path/to/foo.dart.js'); // -> '.js'
  ///
  /// If the file name starts with a `.`, then it is not considered an
  /// extension:
  ///
  ///     context.extension('~/.bashrc');    // -> ''
  ///     context.extension('~/.notes.txt'); // -> '.txt'
  String extension(String path) => _parse(path).extension;

  // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed.
  /// Returns the root of [path] if it's absolute, or an empty string if it's
  /// relative.
  ///
  ///     // Unix
  ///     context.rootPrefix('path/to/foo'); // -> ''
  ///     context.rootPrefix('/path/to/foo'); // -> '/'
  ///
  ///     // Windows
  ///     context.rootPrefix(r'path\to\foo'); // -> ''
  ///     context.rootPrefix(r'C:\path\to\foo'); // -> r'C:\'
  ///
  ///     // URL
  ///     context.rootPrefix('path/to/foo'); // -> ''
  ///     context.rootPrefix('http://dartlang.org/path/to/foo');
  ///       // -> 'http://dartlang.org'
  String rootPrefix(String path) => path.substring(0, style.rootLength(path));

  /// Returns `true` if [path] is an absolute path and `false` if it is a
  /// relative path.
  ///
  /// On POSIX systems, absolute paths start with a `/` (forward slash). On
  /// Windows, an absolute path starts with `\\`, or a drive letter followed by
  /// `:/` or `:\`. For URLs, absolute paths either start with a protocol and
  /// optional hostname (e.g. `http://dartlang.org`, `file://`) or with a `/`.
  ///
  /// URLs that start with `/` are known as "root-relative", since they're
  /// relative to the root of the current URL. Since root-relative paths are
  /// still absolute in every other sense, [isAbsolute] will return true for
  /// them. They can be detected using [isRootRelative].
  bool isAbsolute(String path) => style.rootLength(path) > 0;

  /// Returns `true` if [path] is a relative path and `false` if it is absolute.
  /// On POSIX systems, absolute paths start with a `/` (forward slash). On
  /// Windows, an absolute path starts with `\\`, or a drive letter followed by
  /// `:/` or `:\`.
  bool isRelative(String path) => !this.isAbsolute(path);

  /// Returns `true` if [path] is a root-relative path and `false` if it's not.
  ///
  /// URLs that start with `/` are known as "root-relative", since they're
  /// relative to the root of the current URL. Since root-relative paths are
  /// still absolute in every other sense, [isAbsolute] will return true for
  /// them. They can be detected using [isRootRelative].
  ///
  /// No POSIX and Windows paths are root-relative.
  bool isRootRelative(String path) => style.isRootRelative(path);

  /// Joins the given path parts into a single path. Example:
  ///
  ///     context.join('path', 'to', 'foo'); // -> 'path/to/foo'
  ///
  /// If any part ends in a path separator, then a redundant separator will not
  /// be added:
  ///
  ///     context.join('path/', 'to', 'foo'); // -> 'path/to/foo
  ///
  /// If a part is an absolute path, then anything before that will be ignored:
  ///
  ///     context.join('path', '/to', 'foo'); // -> '/to/foo'
  ///
  String join(String part1,
      [String part2,
      String part3,
      String part4,
      String part5,
      String part6,
      String part7,
      String part8]) {
    var parts = <String>[
      part1,
      part2,
      part3,
      part4,
      part5,
      part6,
      part7,
      part8
    ];
    _validateArgList("join", parts);
    return joinAll(parts.where((part) => part != null));
  }

  /// Joins the given path parts into a single path. Example:
  ///
  ///     context.joinAll(['path', 'to', 'foo']); // -> 'path/to/foo'
  ///
  /// If any part ends in a path separator, then a redundant separator will not
  /// be added:
  ///
  ///     context.joinAll(['path/', 'to', 'foo']); // -> 'path/to/foo
  ///
  /// If a part is an absolute path, then anything before that will be ignored:
  ///
  ///     context.joinAll(['path', '/to', 'foo']); // -> '/to/foo'
  ///
  /// For a fixed number of parts, [join] is usually terser.
  String joinAll(Iterable<String> parts) {
    var buffer = StringBuffer();
    var needsSeparator = false;
    var isAbsoluteAndNotRootRelative = false;

    for (var part in parts.where((part) => part != '')) {
      if (this.isRootRelative(part) && isAbsoluteAndNotRootRelative) {
        // If the new part is root-relative, it preserves the previous root but
        // replaces the path after it.
        var parsed = _parse(part);
        var path = buffer.toString();
        parsed.root =
            path.substring(0, style.rootLength(path, withDrive: true));
        if (style.needsSeparator(parsed.root)) {
          parsed.separators[0] = style.separator;
        }
        buffer.clear();
        buffer.write(parsed.toString());
      } else if (this.isAbsolute(part)) {
        isAbsoluteAndNotRootRelative = !this.isRootRelative(part);
        // An absolute path discards everything before it.
        buffer.clear();
        buffer.write(part);
      } else {
        if (part.length > 0 && style.containsSeparator(part[0])) {
          // The part starts with a separator, so we don't need to add one.
        } else if (needsSeparator) {
          buffer.write(separator);
        }

        buffer.write(part);
      }

      // Unless this part ends with a separator, we'll need to add one before
      // the next part.
      needsSeparator = style.needsSeparator(part);
    }

    return buffer.toString();
  }

  // TODO(nweiz): add a UNC example for Windows once issue 7323 is fixed.
  /// Splits [path] into its components using the current platform's
  /// [separator]. Example:
  ///
  ///     context.split('path/to/foo'); // -> ['path', 'to', 'foo']
  ///
  /// The path will *not* be normalized before splitting.
  ///
  ///     context.split('path/../foo'); // -> ['path', '..', 'foo']
  ///
  /// If [path] is absolute, the root directory will be the first element in the
  /// array. Example:
  ///
  ///     // Unix
  ///     context.split('/path/to/foo'); // -> ['/', 'path', 'to', 'foo']
  ///
  ///     // Windows
  ///     context.split(r'C:\path\to\foo'); // -> [r'C:\', 'path', 'to', 'foo']
  List<String> split(String path) {
    var parsed = _parse(path);
    // Filter out empty parts that exist due to multiple separators in a row.
    parsed.parts = parsed.parts.where((part) => !part.isEmpty).toList();
    if (parsed.root != null) parsed.parts.insert(0, parsed.root);
    return parsed.parts;
  }

  /// Canonicalizes [path].
  ///
  /// This is guaranteed to return the same path for two different input paths
  /// if and only if both input paths point to the same location. Unlike
  /// [normalize], it returns absolute paths when possible and canonicalizes
  /// ASCII case on Windows.
  ///
  /// Note that this does not resolve symlinks.
  ///
  /// If you want a map that uses path keys, it's probably more efficient to
  /// pass [equals] and [hash] to [new HashMap] than it is to canonicalize every
  /// key.
  String canonicalize(String path) {
    path = absolute(path);
    if (style != Style.windows && !_needsNormalization(path)) return path;

    var parsed = _parse(path);
    parsed.normalize(canonicalize: true);
    return parsed.toString();
  }

  /// Normalizes [path], simplifying it by handling `..`, and `.`, and
  /// removing redundant path separators whenever possible.
  ///
  /// Note that this is *not* guaranteed to return the same result for two
  /// equivalent input paths. For that, see [canonicalize]. Or, if you're using
  /// paths as map keys, pass [equals] and [hash] to [new HashMap].
  ///
  ///     context.normalize('path/./to/..//file.text'); // -> 'path/file.txt'
  String normalize(String path) {
    if (!_needsNormalization(path)) return path;

    var parsed = _parse(path);
    parsed.normalize();
    return parsed.toString();
  }

  /// Returns whether [path] needs to be normalized.
  bool _needsNormalization(String path) {
    var start = 0;
    var codeUnits = path.codeUnits;
    int previousPrevious;
    int previous;

    // Skip past the root before we start looking for snippets that need
    // normalization. We want to normalize "//", but not when it's part of
    // "http://".
    var root = style.rootLength(path);
    if (root != 0) {
      start = root;
      previous = chars.SLASH;

      // On Windows, the root still needs to be normalized if it contains a
      // forward slash.
      if (style == Style.windows) {
        for (var i = 0; i < root; i++) {
          if (codeUnits[i] == chars.SLASH) return true;
        }
      }
    }

    for (var i = start; i < codeUnits.length; i++) {
      var codeUnit = codeUnits[i];
      if (style.isSeparator(codeUnit)) {
        // Forward slashes in Windows paths are normalized to backslashes.
        if (style == Style.windows && codeUnit == chars.SLASH) return true;

        // Multiple separators are normalized to single separators.
        if (previous != null && style.isSeparator(previous)) return true;

        // Single dots and double dots are normalized to directory traversals.
        //
        // This can return false positives for ".../", but that's unlikely
        // enough that it's probably not going to cause performance issues.
        if (previous == chars.PERIOD &&
            (previousPrevious == null ||
                previousPrevious == chars.PERIOD ||
                style.isSeparator(previousPrevious))) {
          return true;
        }
      }

      previousPrevious = previous;
      previous = codeUnit;
    }

    // Empty paths are normalized to ".".
    if (previous == null) return true;

    // Trailing separators are removed.
    if (style.isSeparator(previous)) return true;

    // Single dots and double dots are normalized to directory traversals.
    if (previous == chars.PERIOD &&
        (previousPrevious == null ||
            style.isSeparator(previousPrevious) ||
            previousPrevious == chars.PERIOD)) {
      return true;
    }

    return false;
  }

  /// Attempts to convert [path] to an equivalent relative path relative to
  /// [root].
  ///
  ///     var context = new Context(current: '/root/path');
  ///     context.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
  ///     context.relative('/root/other.dart'); // -> '../other.dart'
  ///
  /// If the [from] argument is passed, [path] is made relative to that instead.
  ///
  ///     context.relative('/root/path/a/b.dart',
  ///         from: '/root/path'); // -> 'a/b.dart'
  ///     context.relative('/root/other.dart',
  ///         from: '/root/path'); // -> '../other.dart'
  ///
  /// If [path] and/or [from] are relative paths, they are assumed to be
  /// relative to [current].
  ///
  /// Since there is no relative path from one drive letter to another on
  /// Windows, this will return an absolute path in that case.
  ///
  ///     context.relative(r'D:\other', from: r'C:\other'); // -> 'D:\other'
  ///
  /// This will also return an absolute path if an absolute [path] is passed to
  /// a context with a relative path for [current].
  ///
  ///     var context = new Context(r'some/relative/path');
  ///     context.relative(r'/absolute/path'); // -> '/absolute/path'
  ///
  /// If [root] is relative, it may be impossible to determine a path from
  /// [from] to [path]. For example, if [root] and [path] are "." and [from] is
  /// "/", no path can be determined. In this case, a [PathException] will be
  /// thrown.
  String relative(String path, {String from}) {
    // Avoid expensive computation if the path is already relative.
    if (from == null && this.isRelative(path)) return this.normalize(path);

    from = from == null ? current : absolute(from);

    // We can't determine the path from a relative path to an absolute path.
    if (this.isRelative(from) && this.isAbsolute(path)) {
      return this.normalize(path);
    }

    // If the given path is relative, resolve it relative to the context's
    // current directory.
    if (this.isRelative(path) || this.isRootRelative(path)) {
      path = this.absolute(path);
    }

    // If the path is still relative and `from` is absolute, we're unable to
    // find a path from `from` to `path`.
    if (this.isRelative(path) && this.isAbsolute(from)) {
      throw PathException('Unable to find a path to "$path" from "$from".');
    }

    var fromParsed = _parse(from)..normalize();
    var pathParsed = _parse(path)..normalize();

    if (fromParsed.parts.length > 0 && fromParsed.parts[0] == '.') {
      return pathParsed.toString();
    }

    // If the root prefixes don't match (for example, different drive letters
    // on Windows), then there is no relative path, so just return the absolute
    // one. In Windows, drive letters are case-insenstive and we allow
    // calculation of relative paths, even if a path has not been normalized.
    if (fromParsed.root != pathParsed.root &&
        ((fromParsed.root == null || pathParsed.root == null) ||
            !style.pathsEqual(fromParsed.root, pathParsed.root))) {
      return pathParsed.toString();
    }

    // Strip off their common prefix.
    while (fromParsed.parts.length > 0 &&
        pathParsed.parts.length > 0 &&
        style.pathsEqual(fromParsed.parts[0], pathParsed.parts[0])) {
      fromParsed.parts.removeAt(0);
      fromParsed.separators.removeAt(1);
      pathParsed.parts.removeAt(0);
      pathParsed.separators.removeAt(1);
    }

    // If there are any directories left in the from path, we need to walk up
    // out of them. If a directory left in the from path is '..', it cannot
    // be cancelled by adding a '..'.
    if (fromParsed.parts.length > 0 && fromParsed.parts[0] == '..') {
      throw PathException('Unable to find a path to "$path" from "$from".');
    }
    pathParsed.parts.insertAll(0, List.filled(fromParsed.parts.length, '..'));
    pathParsed.separators[0] = '';
    pathParsed.separators
        .insertAll(1, List.filled(fromParsed.parts.length, style.separator));

    // Corner case: the paths completely collapsed.
    if (pathParsed.parts.length == 0) return '.';

    // Corner case: path was '.' and some '..' directories were added in front.
    // Don't add a final '/.' in that case.
    if (pathParsed.parts.length > 1 && pathParsed.parts.last == '.') {
      pathParsed.parts.removeLast();
      pathParsed.separators
        ..removeLast()
        ..removeLast()
        ..add('');
    }

    // Make it relative.
    pathParsed.root = '';
    pathParsed.removeTrailingSeparators();

    return pathParsed.toString();
  }

  /// Returns `true` if [child] is a path beneath `parent`, and `false`
  /// otherwise.
  ///
  ///     path.isWithin('/root/path', '/root/path/a'); // -> true
  ///     path.isWithin('/root/path', '/root/other'); // -> false
  ///     path.isWithin('/root/path', '/root/path'); // -> false
  bool isWithin(String parent, String child) =>
      _isWithinOrEquals(parent, child) == _PathRelation.within;

  /// Returns `true` if [path1] points to the same location as [path2], and
  /// `false` otherwise.
  ///
  /// The [hash] function returns a hash code that matches these equality
  /// semantics.
  bool equals(String path1, String path2) =>
      _isWithinOrEquals(path1, path2) == _PathRelation.equal;

  /// Compares two paths and returns an enum value indicating their relationship
  /// to one another.
  ///
  /// This never returns [_PathRelation.inconclusive].
  _PathRelation _isWithinOrEquals(String parent, String child) {
    // Make both paths the same level of relative. We're only able to do the
    // quick comparison if both paths are in the same format, and making a path
    // absolute is faster than making it relative.
    var parentIsAbsolute = isAbsolute(parent);
    var childIsAbsolute = isAbsolute(child);
    if (parentIsAbsolute && !childIsAbsolute) {
      child = absolute(child);
      if (style.isRootRelative(parent)) parent = absolute(parent);
    } else if (childIsAbsolute && !parentIsAbsolute) {
      parent = absolute(parent);
      if (style.isRootRelative(child)) child = absolute(child);
    } else if (childIsAbsolute && parentIsAbsolute) {
      var childIsRootRelative = style.isRootRelative(child);
      var parentIsRootRelative = style.isRootRelative(parent);

      if (childIsRootRelative && !parentIsRootRelative) {
        child = absolute(child);
      } else if (parentIsRootRelative && !childIsRootRelative) {
        parent = absolute(parent);
      }
    }

    var result = _isWithinOrEqualsFast(parent, child);
    if (result != _PathRelation.inconclusive) return result;

    String relative;
    try {
      relative = this.relative(child, from: parent);
    } on PathException catch (_) {
      // If no relative path from [parent] to [child] is found, [child]
      // definitely isn't a child of [parent].
      return _PathRelation.different;
    }

    if (!this.isRelative(relative)) return _PathRelation.different;
    if (relative == '.') return _PathRelation.equal;
    if (relative == '..') return _PathRelation.different;
    return (relative.length >= 3 &&
            relative.startsWith('..') &&
            style.isSeparator(relative.codeUnitAt(2)))
        ? _PathRelation.different
        : _PathRelation.within;
  }

  /// An optimized implementation of [_isWithinOrEquals] that doesn't handle a
  /// few complex cases.
  _PathRelation _isWithinOrEqualsFast(String parent, String child) {
    // Normally we just bail when we see "." path components, but we can handle
    // a single dot easily enough.
    if (parent == '.') parent = '';

    var parentRootLength = style.rootLength(parent);
    var childRootLength = style.rootLength(child);

    // If the roots aren't the same length, we know both paths are absolute or
    // both are root-relative, and thus that the roots are meaningfully
    // different.
    //
    //     isWithin("C:/bar", "//foo/bar/baz") //=> false
    //     isWithin("http://example.com/", "http://google.com/bar") //=> false
    if (parentRootLength != childRootLength) return _PathRelation.different;

    // Make sure that the roots are textually the same as well.
    //
    //     isWithin("C:/bar", "D:/bar/baz") //=> false
    //     isWithin("http://example.com/", "http://example.org/bar") //=> false
    for (var i = 0; i < parentRootLength; i++) {
      var parentCodeUnit = parent.codeUnitAt(i);
      var childCodeUnit = child.codeUnitAt(i);
      if (!style.codeUnitsEqual(parentCodeUnit, childCodeUnit)) {
        return _PathRelation.different;
      }
    }

    // Start by considering the last code unit as a separator, since
    // semantically we're starting at a new path component even if we're
    // comparing relative paths.
    var lastCodeUnit = chars.SLASH;

    /// The index of the last separator in [parent].
    int lastParentSeparator;

    // Iterate through both paths as long as they're semantically identical.
    var parentIndex = parentRootLength;
    var childIndex = childRootLength;
    while (parentIndex < parent.length && childIndex < child.length) {
      var parentCodeUnit = parent.codeUnitAt(parentIndex);
      var childCodeUnit = child.codeUnitAt(childIndex);
      if (style.codeUnitsEqual(parentCodeUnit, childCodeUnit)) {
        if (style.isSeparator(parentCodeUnit)) {
          lastParentSeparator = parentIndex;
        }

        lastCodeUnit = parentCodeUnit;
        parentIndex++;
        childIndex++;
        continue;
      }

      // Ignore multiple separators in a row.
      if (style.isSeparator(parentCodeUnit) &&
          style.isSeparator(lastCodeUnit)) {
        lastParentSeparator = parentIndex;
        parentIndex++;
        continue;
      } else if (style.isSeparator(childCodeUnit) &&
          style.isSeparator(lastCodeUnit)) {
        childIndex++;
        continue;
      }

      // If a dot comes after a separator, it may be a directory traversal
      // operator. To check that, we need to know if it's followed by either
      // "/" or "./". Otherwise, it's just a normal non-matching character.
      //
      //     isWithin("foo/./bar", "foo/bar/baz") //=> true
      //     isWithin("foo/bar/../baz", "foo/bar/.foo") //=> false
      if (parentCodeUnit == chars.PERIOD && style.isSeparator(lastCodeUnit)) {
        parentIndex++;

        // We've hit "/." at the end of the parent path, which we can ignore,
        // since the paths were equivalent up to this point.
        if (parentIndex == parent.length) break;
        parentCodeUnit = parent.codeUnitAt(parentIndex);

        // We've hit "/./", which we can ignore.
        if (style.isSeparator(parentCodeUnit)) {
          lastParentSeparator = parentIndex;
          parentIndex++;
          continue;
        }

        // We've hit "/..", which may be a directory traversal operator that
        // we can't handle on the fast track.
        if (parentCodeUnit == chars.PERIOD) {
          parentIndex++;
          if (parentIndex == parent.length ||
              style.isSeparator(parent.codeUnitAt(parentIndex))) {
            return _PathRelation.inconclusive;
          }
        }

        // If this isn't a directory traversal, fall through so we hit the
        // normal handling for mismatched paths.
      }

      // This is the same logic as above, but for the child path instead of the
      // parent.
      if (childCodeUnit == chars.PERIOD && style.isSeparator(lastCodeUnit)) {
        childIndex++;
        if (childIndex == child.length) break;
        childCodeUnit = child.codeUnitAt(childIndex);

        if (style.isSeparator(childCodeUnit)) {
          childIndex++;
          continue;
        }

        if (childCodeUnit == chars.PERIOD) {
          childIndex++;
          if (childIndex == child.length ||
              style.isSeparator(child.codeUnitAt(childIndex))) {
            return _PathRelation.inconclusive;
          }
        }
      }

      // If we're here, we've hit two non-matching, non-significant characters.
      // As long as the remainders of the two paths don't have any unresolved
      // ".." components, we can be confident that [child] is not within
      // [parent].
      var childDirection = _pathDirection(child, childIndex);
      if (childDirection != _PathDirection.belowRoot) {
        return _PathRelation.inconclusive;
      }

      var parentDirection = _pathDirection(parent, parentIndex);
      if (parentDirection != _PathDirection.belowRoot) {
        return _PathRelation.inconclusive;
      }

      return _PathRelation.different;
    }

    // If the child is shorter than the parent, it's probably not within the
    // parent. The only exception is if the parent has some weird ".." stuff
    // going on, in which case we do the slow check.
    //
    //     isWithin("foo/bar/baz", "foo/bar") //=> false
    //     isWithin("foo/bar/baz/../..", "foo/bar") //=> true
    if (childIndex == child.length) {
      if (parentIndex == parent.length ||
          style.isSeparator(parent.codeUnitAt(parentIndex))) {
        lastParentSeparator = parentIndex;
      } else {
        lastParentSeparator ??= math.max(0, parentRootLength - 1);
      }

      var direction =
          _pathDirection(parent, lastParentSeparator ?? parentRootLength - 1);
      if (direction == _PathDirection.atRoot) return _PathRelation.equal;
      return direction == _PathDirection.aboveRoot
          ? _PathRelation.inconclusive
          : _PathRelation.different;
    }

    // We've reached the end of the parent path, which means it's time to make a
    // decision. Before we do, though, we'll check the rest of the child to see
    // what that tells us.
    var direction = _pathDirection(child, childIndex);

    // If there are no more components in the child, then it's the same as
    // the parent.
    //
    //     isWithin("foo/bar", "foo/bar") //=> false
    //     isWithin("foo/bar", "foo/bar//") //=> false
    //     equals("foo/bar", "foo/bar") //=> true
    //     equals("foo/bar", "foo/bar//") //=> true
    if (direction == _PathDirection.atRoot) return _PathRelation.equal;

    // If there are unresolved ".." components in the child, no decision we make
    // will be valid. We'll abort and do the slow check instead.
    //
    //     isWithin("foo/bar", "foo/bar/..") //=> false
    //     isWithin("foo/bar", "foo/bar/baz/bang/../../..") //=> false
    //     isWithin("foo/bar", "foo/bar/baz/bang/../../../bar/baz") //=> true
    if (direction == _PathDirection.aboveRoot) {
      return _PathRelation.inconclusive;
    }

    // The child is within the parent if and only if we're on a separator
    // boundary.
    //
    //     isWithin("foo/bar", "foo/bar/baz") //=> true
    //     isWithin("foo/bar/", "foo/bar/baz") //=> true
    //     isWithin("foo/bar", "foo/barbaz") //=> false
    return (style.isSeparator(child.codeUnitAt(childIndex)) ||
            style.isSeparator(lastCodeUnit))
        ? _PathRelation.within
        : _PathRelation.different;
  }

  // Returns a [_PathDirection] describing the path represented by [codeUnits]
  // starting at [index].
  //
  // This ignores leading separators.
  //
  //     pathDirection("foo") //=> below root
  //     pathDirection("foo/bar/../baz") //=> below root
  //     pathDirection("//foo/bar/baz") //=> below root
  //     pathDirection("/") //=> at root
  //     pathDirection("foo/..") //=> at root
  //     pathDirection("foo/../baz") //=> reaches root
  //     pathDirection("foo/../..") //=> above root
  //     pathDirection("foo/../../foo/bar/baz") //=> above root
  _PathDirection _pathDirection(String path, int index) {
    var depth = 0;
    var reachedRoot = false;
    var i = index;
    while (i < path.length) {
      // Ignore initial separators or doubled separators.
      while (i < path.length && style.isSeparator(path.codeUnitAt(i))) {
        i++;
      }

      // If we're at the end, stop.
      if (i == path.length) break;

      // Move through the path component to the next separator.
      var start = i;
      while (i < path.length && !style.isSeparator(path.codeUnitAt(i))) {
        i++;
      }

      // See if the path component is ".", "..", or a name.
      if (i - start == 1 && path.codeUnitAt(start) == chars.PERIOD) {
        // Don't change the depth.
      } else if (i - start == 2 &&
          path.codeUnitAt(start) == chars.PERIOD &&
          path.codeUnitAt(start + 1) == chars.PERIOD) {
        // ".." backs out a directory.
        depth--;

        // If we work back beyond the root, stop.
        if (depth < 0) break;

        // Record that we reached the root so we don't return
        // [_PathDirection.belowRoot].
        if (depth == 0) reachedRoot = true;
      } else {
        // Step inside a directory.
        depth++;
      }

      // If we're at the end, stop.
      if (i == path.length) break;

      // Move past the separator.
      i++;
    }

    if (depth < 0) return _PathDirection.aboveRoot;
    if (depth == 0) return _PathDirection.atRoot;
    if (reachedRoot) return _PathDirection.reachesRoot;
    return _PathDirection.belowRoot;
  }

  /// Returns a hash code for [path] that matches the semantics of [equals].
  ///
  /// Note that the same path may have different hash codes in different
  /// [Context]s.
  int hash(String path) {
    // Make [path] absolute to ensure that equivalent relative and absolute
    // paths have the same hash code.
    path = absolute(path);

    var result = _hashFast(path);
    if (result != null) return result;

    var parsed = _parse(path);
    parsed.normalize();
    return _hashFast(parsed.toString());
  }

  /// An optimized implementation of [hash] that doesn't handle internal `..`
  /// components.
  ///
  /// This will handle `..` components that appear at the beginning of the path.
  int _hashFast(String path) {
    var hash = 4603;
    var beginning = true;
    var wasSeparator = true;
    for (var i = 0; i < path.length; i++) {
      var codeUnit = style.canonicalizeCodeUnit(path.codeUnitAt(i));

      // Take advantage of the fact that collisions are allowed to ignore
      // separators entirely. This lets us avoid worrying about cases like
      // multiple trailing slashes.
      if (style.isSeparator(codeUnit)) {
        wasSeparator = true;
        continue;
      }

      if (codeUnit == chars.PERIOD && wasSeparator) {
        // If a dot comes after a separator, it may be a directory traversal
        // operator. To check that, we need to know if it's followed by either
        // "/" or "./". Otherwise, it's just a normal character.
        //
        //     hash("foo/./bar") == hash("foo/bar")

        // We've hit "/." at the end of the path, which we can ignore.
        if (i + 1 == path.length) break;

        var next = path.codeUnitAt(i + 1);

        // We can just ignore "/./", since they don't affect the semantics of
        // the path.
        if (style.isSeparator(next)) continue;

        // If the path ends with "/.." or contains "/../", we need to
        // canonicalize it before we can hash it. We make an exception for ".."s
        // at the beginning of the path, since those may appear even in a
        // canonicalized path.
        if (!beginning &&
            next == chars.PERIOD &&
            (i + 2 == path.length ||
                style.isSeparator(path.codeUnitAt(i + 2)))) {
          return null;
        }
      }

      // Make sure [hash] stays under 32 bits even after multiplication.
      hash &= 0x3FFFFFF;
      hash *= 33;
      hash ^= codeUnit;
      wasSeparator = false;
      beginning = false;
    }
    return hash;
  }

  /// Removes a trailing extension from the last part of [path].
  ///
  ///     context.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
  String withoutExtension(String path) {
    var parsed = _parse(path);

    for (var i = parsed.parts.length - 1; i >= 0; i--) {
      if (!parsed.parts[i].isEmpty) {
        parsed.parts[i] = parsed.basenameWithoutExtension;
        break;
      }
    }

    return parsed.toString();
  }

  /// Returns [path] with the trailing extension set to [extension].
  ///
  /// If [path] doesn't have a trailing extension, this just adds [extension] to
  /// the end.
  ///
  ///     context.setExtension('path/to/foo.dart', '.js')
  ///       // -> 'path/to/foo.js'
  ///     context.setExtension('path/to/foo.dart.js', '.map')
  ///       // -> 'path/to/foo.dart.map'
  ///     context.setExtension('path/to/foo', '.js')
  ///       // -> 'path/to/foo.js'
  String setExtension(String path, String extension) =>
      withoutExtension(path) + extension;

  /// Returns the path represented by [uri], which may be a [String] or a [Uri].
  ///
  /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
  /// style, this will just convert [uri] to a string.
  ///
  ///     // POSIX
  ///     context.fromUri('file:///path/to/foo')
  ///       // -> '/path/to/foo'
  ///
  ///     // Windows
  ///     context.fromUri('file:///C:/path/to/foo')
  ///       // -> r'C:\path\to\foo'
  ///
  ///     // URL
  ///     context.fromUri('http://dartlang.org/path/to/foo')
  ///       // -> 'http://dartlang.org/path/to/foo'
  ///
  /// If [uri] is relative, a relative path will be returned.
  ///
  ///     path.fromUri('path/to/foo'); // -> 'path/to/foo'
  String fromUri(uri) => style.pathFromUri(_parseUri(uri));

  /// Returns the URI that represents [path].
  ///
  /// For POSIX and Windows styles, this will return a `file:` URI. For the URL
  /// style, this will just convert [path] to a [Uri].
  ///
  ///     // POSIX
  ///     context.toUri('/path/to/foo')
  ///       // -> Uri.parse('file:///path/to/foo')
  ///
  ///     // Windows
  ///     context.toUri(r'C:\path\to\foo')
  ///       // -> Uri.parse('file:///C:/path/to/foo')
  ///
  ///     // URL
  ///     context.toUri('http://dartlang.org/path/to/foo')
  ///       // -> Uri.parse('http://dartlang.org/path/to/foo')
  Uri toUri(String path) {
    if (isRelative(path)) {
      return style.relativePathToUri(path);
    } else {
      return style.absolutePathToUri(join(current, path));
    }
  }

  /// Returns a terse, human-readable representation of [uri].
  ///
  /// [uri] can be a [String] or a [Uri]. If it can be made relative to the
  /// current working directory, that's done. Otherwise, it's returned as-is.
  /// This gracefully handles non-`file:` URIs for [Style.posix] and
  /// [Style.windows].
  ///
  /// The returned value is meant for human consumption, and may be either URI-
  /// or path-formatted.
  ///
  ///     // POSIX
  ///     var context = new Context(current: '/root/path');
  ///     context.prettyUri('file:///root/path/a/b.dart'); // -> 'a/b.dart'
  ///     context.prettyUri('http://dartlang.org/'); // -> 'http://dartlang.org'
  ///
  ///     // Windows
  ///     var context = new Context(current: r'C:\root\path');
  ///     context.prettyUri('file:///C:/root/path/a/b.dart'); // -> r'a\b.dart'
  ///     context.prettyUri('http://dartlang.org/'); // -> 'http://dartlang.org'
  ///
  ///     // URL
  ///     var context = new Context(current: 'http://dartlang.org/root/path');
  ///     context.prettyUri('http://dartlang.org/root/path/a/b.dart');
  ///         // -> r'a/b.dart'
  ///     context.prettyUri('file:///root/path'); // -> 'file:///root/path'
  String prettyUri(uri) {
    var typedUri = _parseUri(uri);
    if (typedUri.scheme == 'file' && style == Style.url) {
      return typedUri.toString();
    } else if (typedUri.scheme != 'file' &&
        typedUri.scheme != '' &&
        style != Style.url) {
      return typedUri.toString();
    }

    var path = normalize(fromUri(typedUri));
    var rel = relative(path);

    // Only return a relative path if it's actually shorter than the absolute
    // path. This avoids ugly things like long "../" chains to get to the root
    // and then go back down.
    return split(rel).length > split(path).length ? path : rel;
  }

  ParsedPath _parse(String path) => ParsedPath.parse(path, style);
}

/// Parses argument if it's a [String] or returns it intact if it's a [Uri].
///
/// Throws an [ArgumentError] otherwise.
Uri _parseUri(uri) {
  if (uri is String) return Uri.parse(uri);
  if (uri is Uri) return uri;
  throw ArgumentError.value(uri, 'uri', 'Value must be a String or a Uri');
}

/// Validates that there are no non-null arguments following a null one and
/// throws an appropriate [ArgumentError] on failure.
void _validateArgList(String method, List<String> args) {
  for (var i = 1; i < args.length; i++) {
    // Ignore nulls hanging off the end.
    if (args[i] == null || args[i - 1] != null) continue;

    int numArgs;
    for (numArgs = args.length; numArgs >= 1; numArgs--) {
      if (args[numArgs - 1] != null) break;
    }

    // Show the arguments.
    var message = StringBuffer();
    message.write("$method(");
    message.write(args
        .take(numArgs)
        .map((arg) => arg == null ? "null" : '"$arg"')
        .join(", "));
    message.write("): part ${i - 1} was null, but part $i was not.");
    throw ArgumentError(message.toString());
  }
}

/// An enum of possible return values for [Context._pathDirection].
class _PathDirection {
  /// The path contains enough ".." components that at some point it reaches
  /// above its original root.
  ///
  /// Note that this applies even if the path ends beneath its original root. It
  /// takes precendence over any other return values that may apple.
  static const aboveRoot = _PathDirection("above root");

  /// The path contains enough ".." components that it ends at its original
  /// root.
  static const atRoot = _PathDirection("at root");

  /// The path contains enough ".." components that at some point it reaches its
  /// original root, but it ends beneath that root.
  static const reachesRoot = _PathDirection("reaches root");

  /// The path never reaches to or above its original root.
  static const belowRoot = _PathDirection("below root");

  final String name;

  const _PathDirection(this.name);

  String toString() => name;
}

/// An enum of possible return values for [Context._isWithinOrEquals].
class _PathRelation {
  /// The first path is a proper parent of the second.
  ///
  /// For example, `foo` is a proper parent of `foo/bar`, but not of `foo`.
  static const within = _PathRelation("within");

  /// The two paths are equivalent.
  ///
  /// For example, `foo//bar` is equivalent to `foo/bar`.
  static const equal = _PathRelation("equal");

  /// The first path is neither a parent of nor equal to the second.
  static const different = _PathRelation("different");

  /// We couldn't quickly determine any information about the paths'
  /// relationship to each other.
  ///
  /// Only returned by [Context._isWithinOrEqualsFast].
  static const inconclusive = _PathRelation("inconclusive");

  final String name;

  const _PathRelation(this.name);

  String toString() => name;
}
