// 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 '../characters.dart' as chars;
import '../internal_style.dart';
import '../parsed_path.dart';
import '../utils.dart';

// `0b100000` can be bitwise-ORed with uppercase ASCII letters to get their
// lowercase equivalents.
const _asciiCaseBit = 0x20;

/// The style for Windows paths.
class WindowsStyle extends InternalStyle {
  WindowsStyle();

  final name = 'windows';
  final separator = '\\';
  final separators = const ['/', '\\'];

  // Deprecated properties.

  final separatorPattern = new RegExp(r'[/\\]');
  final needsSeparatorPattern = new RegExp(r'[^/\\]$');
  final rootPattern = new RegExp(r'^(\\\\[^\\]+\\[^\\/]+|[a-zA-Z]:[/\\])');
  final relativeRootPattern = new RegExp(r"^[/\\](?![/\\])");

  bool containsSeparator(String path) => path.contains('/');

  bool isSeparator(int codeUnit) =>
      codeUnit == chars.SLASH || codeUnit == chars.BACKSLASH;

  bool needsSeparator(String path) {
    if (path.isEmpty) return false;
    return !isSeparator(path.codeUnitAt(path.length - 1));
  }

  int rootLength(String path, {bool withDrive: false}) {
    if (path.isEmpty) return 0;
    if (path.codeUnitAt(0) == chars.SLASH) return 1;
    if (path.codeUnitAt(0) == chars.BACKSLASH) {
      if (path.length < 2 || path.codeUnitAt(1) != chars.BACKSLASH) return 1;
      // The path is a network share. Search for up to two '\'s, as they are
      // the server and share - and part of the root part.
      var index = path.indexOf('\\', 2);
      if (index > 0) {
        index = path.indexOf('\\', index + 1);
        if (index > 0) return index;
      }
      return path.length;
    }
    // If the path is of the form 'C:/' or 'C:\', with C being any letter, it's
    // a root part.
    if (path.length < 3) return 0;
    // Check for the letter.
    if (!isAlphabetic(path.codeUnitAt(0))) return 0;
    // Check for the ':'.
    if (path.codeUnitAt(1) != chars.COLON) return 0;
    // Check for either '/' or '\'.
    if (!isSeparator(path.codeUnitAt(2))) return 0;
    return 3;
  }

  bool isRootRelative(String path) => rootLength(path) == 1;

  String getRelativeRoot(String path) {
    var length = rootLength(path);
    if (length == 1) return path[0];
    return null;
  }

  String pathFromUri(Uri uri) {
    if (uri.scheme != '' && uri.scheme != 'file') {
      throw new ArgumentError("Uri $uri must have scheme 'file:'.");
    }

    var path = uri.path;
    if (uri.host == '') {
      // Drive-letter paths look like "file:///C:/path/to/file". The
      // replaceFirst removes the extra initial slash.
      if (path.startsWith('/')) path = path.replaceFirst("/", "");
    } else {
      // Network paths look like "file://hostname/path/to/file".
      path = '\\\\${uri.host}$path';
    }
    return Uri.decodeComponent(path.replaceAll("/", "\\"));
  }

  Uri absolutePathToUri(String path) {
    var parsed = new ParsedPath.parse(path, this);
    if (parsed.root.startsWith(r'\\')) {
      // Network paths become "file://server/share/path/to/file".

      // The root is of the form "\\server\share". We want "server" to be the
      // URI host, and "share" to be the first element of the path.
      var rootParts = parsed.root.split('\\').where((part) => part != '');
      parsed.parts.insert(0, rootParts.last);

      if (parsed.hasTrailingSeparator) {
        // If the path has a trailing slash, add a single empty component so the
        // URI has a trailing slash as well.
        parsed.parts.add("");
      }

      return new Uri(
          scheme: 'file', host: rootParts.first, pathSegments: parsed.parts);
    } else {
      // Drive-letter paths become "file:///C:/path/to/file".

      // If the path is a bare root (e.g. "C:\"), [parsed.parts] will currently
      // be empty. We add an empty component so the URL constructor produces
      // "file:///C:/", with a trailing slash. We also add an empty component if
      // the URL otherwise has a trailing slash.
      if (parsed.parts.length == 0 || parsed.hasTrailingSeparator) {
        parsed.parts.add("");
      }

      // Get rid of the trailing "\" in "C:\" because the URI constructor will
      // add a separator on its own.
      parsed.parts.insert(
          0, parsed.root.replaceAll("/", "").replaceAll("\\", ""));

      return new Uri(scheme: 'file', pathSegments: parsed.parts);
    }
  }

  bool codeUnitsEqual(int codeUnit1, int codeUnit2) {
    if (codeUnit1 == codeUnit2) return true;

    /// Forward slashes and backslashes are equivalent on Windows.
    if (codeUnit1 == chars.SLASH) return codeUnit2 == chars.BACKSLASH;
    if (codeUnit1 == chars.BACKSLASH) return codeUnit2 == chars.SLASH;

    // If this check fails, the code units are definitely different. If it
    // succeeds *and* either codeUnit is an ASCII letter, they're equivalent.
    if (codeUnit1 ^ codeUnit2 != _asciiCaseBit) return false;

    // Now we just need to verify that one of the code units is an ASCII letter.
    var upperCase1 = codeUnit1 | _asciiCaseBit;
    return upperCase1 >= chars.LOWER_A && upperCase1 <= chars.LOWER_Z;
  }

  bool pathsEqual(String path1, String path2) {
    if (identical(path1, path2)) return true;
    if (path1.length != path2.length) return false;
    for (var i = 0; i < path1.length; i++) {
      if (!codeUnitsEqual(path1.codeUnitAt(i), path2.codeUnitAt(i))) {
        return false;
      }
    }
    return true;
  }

  int canonicalizeCodeUnit(int codeUnit) {
    if (codeUnit == chars.SLASH) return chars.BACKSLASH;
    if (codeUnit < chars.UPPER_A) return codeUnit;
    if (codeUnit > chars.UPPER_Z) return codeUnit;
    return codeUnit | _asciiCaseBit;
  }

  String canonicalizePart(String part) => part.toLowerCase();
}
