// Copyright (c) 2014, 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 'context.dart';
import 'style.dart';

/// The internal interface for the [Style] type.
///
/// Users should be able to pass around instances of [Style] like an enum, but
/// the members that [Context] uses should be hidden from them. Those members
/// are defined on this class instead.
abstract class InternalStyle extends Style {
  /// The default path separator for this style.
  ///
  /// On POSIX, this is `/`. On Windows, it's `\`.
  String get separator;

  /// Returns whether [path] contains a separator.
  bool containsSeparator(String path);

  /// Returns whether [codeUnit] is the character code of a separator.
  bool isSeparator(int codeUnit);

  /// Returns whether this path component needs a separator after it.
  ///
  /// Windows and POSIX styles just need separators when the previous component
  /// doesn't already end in a separator, but the URL always needs to place a
  /// separator between the root and the first component, even if the root
  /// already ends in a separator character. For example, to join "file://" and
  /// "usr", an additional "/" is needed (making "file:///usr").
  bool needsSeparator(String path);

  /// Returns the number of characters of the root part.
  ///
  /// Returns 0 if the path is relative and 1 if the path is root-relative.
  ///
  /// If [withDrive] is `true`, this should include the drive letter for `file:`
  /// URLs. Non-URL styles may ignore the parameter.
  int rootLength(String path, {bool withDrive: false});

  /// Gets the root prefix of [path] if path is absolute. If [path] is relative,
  /// returns `null`.
  String getRoot(String path) {
    var length = rootLength(path);
    if (length > 0) return path.substring(0, length);
    return isRootRelative(path) ? path[0] : null;
  }

  /// Returns whether [path] is root-relative.
  ///
  /// If [path] is relative or absolute and not root-relative, returns `false`.
  bool isRootRelative(String path);

  /// Returns the path represented by [uri] in this style.
  String pathFromUri(Uri uri);

  /// Returns the URI that represents the relative path made of [parts].
  Uri relativePathToUri(String path) {
    var segments = context.split(path);

    // Ensure that a trailing slash in the path produces a trailing slash in the
    // URL.
    if (isSeparator(path.codeUnitAt(path.length - 1))) segments.add('');
    return new Uri(pathSegments: segments);
  }

  /// Returns the URI that represents [path], which is assumed to be absolute.
  Uri absolutePathToUri(String path);

  /// Returns whether [codeUnit1] and [codeUnit2] are considered equivalent for
  /// this style.
  bool codeUnitsEqual(int codeUnit1, int codeUnit2) => codeUnit1 == codeUnit2;

  /// Returns whether [path1] and [path2] are equivalent.
  ///
  /// This only needs to handle character-by-character comparison; it can assume
  /// the paths are normalized and contain no `..` components.
  bool pathsEqual(String path1, String path2) => path1 == path2;

  int canonicalizeCodeUnit(int codeUnit) => codeUnit;

  String canonicalizePart(String part) => part;
}
