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

/// Utility methods used by more than one library in the package.
library;

import 'errors.dart';

// All ASCII characters that are valid in a package name, with space
// for all the invalid ones (including space).
const String _validPackageNameCharacters =
    r"                                 !  $ &'()*+,-. 0123456789 ; =  "
    r'@ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ abcdefghijklmnopqrstuvwxyz   ~ ';

/// Check if a string is a valid package name.
///
/// Valid package names contain only characters in [_validPackageNameCharacters]
/// and must contain at least one non-'.' character.
///
/// Returns `-1` if the string is valid.
/// Otherwise returns the index of the first invalid character,
/// or `string.length` if the string contains no non-'.' character.
int checkPackageName(String string) {
  // Becomes non-zero if any non-'.' character is encountered.
  var nonDot = 0;
  for (var i = 0; i < string.length; i++) {
    var c = string.codeUnitAt(i);
    if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) {
      return i;
    }
    nonDot += c ^ $dot;
  }
  if (nonDot == 0) return string.length;
  return -1;
}

/// Validate that a [Uri] is a valid `package:` URI.
///
/// Used to validate user input.
///
/// Returns the package name extracted from the package URI,
/// which is the path segment between `package:` and the first `/`.
String checkValidPackageUri(Uri packageUri, String name) {
  if (packageUri.scheme != 'package') {
    throw PackageConfigArgumentError(packageUri, name, 'Not a package: URI');
  }
  if (packageUri.hasAuthority) {
    throw PackageConfigArgumentError(
      packageUri,
      name,
      'Package URIs must not have a host part',
    );
  }
  if (packageUri.hasQuery) {
    // A query makes no sense if resolved to a file: URI.
    throw PackageConfigArgumentError(
      packageUri,
      name,
      'Package URIs must not have a query part',
    );
  }
  if (packageUri.hasFragment) {
    // We could leave the fragment after the URL when resolving,
    // but it would be odd if "package:foo/foo.dart#1" and
    // "package:foo/foo.dart#2" were considered different libraries.
    // Keep the syntax open in case we ever get multiple libraries in one file.
    throw PackageConfigArgumentError(
      packageUri,
      name,
      'Package URIs must not have a fragment part',
    );
  }
  if (packageUri.path.startsWith('/')) {
    throw PackageConfigArgumentError(
      packageUri,
      name,
      "Package URIs must not start with a '/'",
    );
  }
  var firstSlash = packageUri.path.indexOf('/');
  if (firstSlash == -1) {
    throw PackageConfigArgumentError(
      packageUri,
      name,
      "Package URIs must start with the package name followed by a '/'",
    );
  }
  var packageName = packageUri.path.substring(0, firstSlash);
  var badIndex = checkPackageName(packageName);
  if (badIndex >= 0) {
    if (packageName.isEmpty) {
      throw PackageConfigArgumentError(
        packageUri,
        name,
        'Package names mus be non-empty',
      );
    }
    if (badIndex == packageName.length) {
      throw PackageConfigArgumentError(
        packageUri,
        name,
        "Package names must contain at least one non-'.' character",
      );
    }
    assert(badIndex < packageName.length);
    var badCharCode = packageName.codeUnitAt(badIndex);
    var badChar = 'U+${badCharCode.toRadixString(16).padLeft(4, '0')}';
    if (badCharCode >= 0x20 && badCharCode <= 0x7e) {
      // Printable character.
      badChar = "'${packageName[badIndex]}' ($badChar)";
    }
    throw PackageConfigArgumentError(
      packageUri,
      name,
      'Package names must not contain $badChar',
    );
  }
  return packageName;
}

/// Checks whether URI is just an absolute directory.
///
/// * It must have a scheme.
/// * It must not have a query or fragment.
/// * The path must end with `/`.
bool isAbsoluteDirectoryUri(Uri uri) {
  if (uri.hasQuery) return false;
  if (uri.hasFragment) return false;
  if (!uri.hasScheme) return false;
  var path = uri.path;
  if (!path.endsWith('/')) return false;
  return true;
}

/// Whether the former URI is a prefix of the latter.
bool isUriPrefix(Uri prefix, Uri path) {
  assert(!prefix.hasFragment);
  assert(!prefix.hasQuery);
  assert(!path.hasQuery);
  assert(!path.hasFragment);
  assert(prefix.path.endsWith('/'));
  return path.toString().startsWith(prefix.toString());
}

/// Appends a trailing `/` if the [path] ends in a non-`/` character.
String trailingSlash(String path) {
  if (path.isEmpty || path.endsWith('/')) return path;
  return '$path/';
}

/// Whether a URI should not be considered relative to the base URI.
///
/// Used to determine whether a parsed root URI is relative
/// to the configuration file or not.
/// If it is relative, then it's rewritten as relative when
/// output again later. If not, it's output as absolute.
bool hasAbsolutePath(Uri uri) =>
    uri.hasScheme || uri.hasAuthority || uri.hasAbsolutePath;

/// Attempts to return a relative path-only URI for [uri].
///
/// First removes any query or fragment part from [uri].
///
/// If [uri] is already relative (has no scheme), it's returned as-is.
/// If that is not desired, the caller can pass `baseUri.resolveUri(uri)`
/// as the [uri] instead.
///
/// If the [uri] has a scheme or authority part which differs from
/// the [baseUri], or if there is no overlap in the paths of the
/// two URIs at all, the [uri] is returned as-is.
///
/// Otherwise the result is a path-only URI which satisfies
/// `baseUri.resolveUri(result) == uri`,
///
/// The `baseUri` must be absolute.
Uri? relativizeUri(Uri? uri, Uri? baseUri) {
  if (baseUri == null) return uri;
  assert(baseUri.isAbsolute);
  if (uri!.hasQuery || uri.hasFragment) {
    uri = Uri(
      scheme: uri.scheme,
      userInfo: uri.hasAuthority ? uri.userInfo : null,
      host: uri.hasAuthority ? uri.host : null,
      port: uri.hasAuthority ? uri.port : null,
      path: uri.path,
    );
  }

  // Already relative. We assume the caller knows what they are doing.
  if (!uri.isAbsolute) return uri;

  if (baseUri.scheme != uri.scheme) {
    return uri;
  }

  // If authority differs, we could remove the scheme, but it's not worth it.
  if (uri.hasAuthority != baseUri.hasAuthority) return uri;
  if (uri.hasAuthority) {
    if (uri.userInfo != baseUri.userInfo ||
        uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
        uri.port != baseUri.port) {
      return uri;
    }
  }

  baseUri = baseUri.normalizePath();
  var base = [...baseUri.pathSegments];
  if (base.isNotEmpty) base.removeLast();
  uri = uri.normalizePath();
  var target = [...uri.pathSegments];
  if (target.isNotEmpty && target.last.isEmpty) target.removeLast();
  var index = 0;
  while (index < base.length && index < target.length) {
    if (base[index] != target[index]) {
      break;
    }
    index++;
  }
  if (index == base.length) {
    if (index == target.length) {
      return Uri(path: './');
    }
    return Uri(path: target.skip(index).join('/'));
  } else if (index > 0) {
    var buffer = StringBuffer();
    for (var n = base.length - index; n > 0; --n) {
      buffer.write('../');
    }
    buffer.writeAll(target.skip(index), '/');
    return Uri(path: buffer.toString());
  } else {
    return uri;
  }
}

// Character constants used by this package.
/// Space character.
const int $space = 0x20;

/// Character `.`.
const int $dot = 0x2e;
