// Copyright (c) 2025, 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:io';

import 'package:path/path.dart' as p;

import 'event.dart';
import 'watch_event.dart';

/// An absolute file path.
extension type AbsolutePath(String _string) {
  /// Whether this immediate parent directory of this path is [directory].
  bool isIn(AbsolutePath directory) => p.dirname(_string) == directory._string;

  AbsolutePath get parent => AbsolutePath(p.dirname(_string));

  /// This path relative to [root].
  ///
  /// Returns the empty string if this path is [root].
  ///
  /// Otherwise, return null if this path does not start with [root].
  RelativePath? tryRelativeTo(AbsolutePath root) {
    if (!_string.startsWith(root._string)) return null;
    if (_string == root._string) return RelativePath('');
    if (_string.substring(root._string.length, root._string.length + 1) !=
        Platform.pathSeparator) {
      return null;
    }
    return RelativePath(_string.substring(root._string.length + 1));
  }

  /// This path relative to [root].
  ///
  /// Returns the empty string if this path is [root].
  ///
  /// Otherwise, throws if this path does not start with [root].
  RelativePath relativeTo(AbsolutePath root) {
    return tryRelativeTo(root) ??
        (throw ArgumentError('$this relativeTo $root'));
  }

  /// This path relative to [root] as a single segment.
  ///
  /// Throws if this path is not a single segment under [root].
  PathSegment segmentRelativeTo(AbsolutePath root) {
    if (!_string.startsWith(root._string)) {
      throw ArgumentError('$this segmentRelativeTo $root');
    }
    if (_string == root._string) throw ArgumentError(root);
    final result = _string.substring(root._string.length + 1);
    return PathSegment(result);
  }

  /// The last path segment of this path.
  RelativePath get basename => RelativePath(p.basename(_string));

  /// Lists the directory at this path, ignoring symlinks.
  List<FileSystemEntity> listSync() =>
      Directory(_string).listSync(followLinks: false);

  /// Watches the directory at this path.
  Stream<FileSystemEvent> watch({bool recursive = false}) =>
      Directory(_string).watch(recursive: recursive);

  /// Gets the [FileSystemEntityType] for this path.
  FileSystemEntityType typeSync() =>
      FileSystemEntity.typeSync(_string, followLinks: false);

  /// Returns this path followed by [path].
  AbsolutePath append(RelativePath path) =>
      AbsolutePath('$_string${Platform.pathSeparator}${path._string}');

  /// Add event for this path.
  WatchEvent get addEvent => WatchEvent(ChangeType.ADD, _string);

  /// Modify event for this path.
  WatchEvent get modifyEvent => WatchEvent(ChangeType.MODIFY, _string);

  /// Remove event for this path.
  WatchEvent get removeEvent => WatchEvent(ChangeType.REMOVE, _string);
}

extension FileSystemEntityExtensions on FileSystemEntity {
  /// The event path relative to [root].
  ///
  /// Throws if not under [root].
  RelativePath pathRelativeTo(AbsolutePath root) =>
      AbsolutePath(path).relativeTo(root);

  /// The path segment under [root].
  ///
  /// Throws if not a single path segment under [root].
  PathSegment pathSegmentRelativeTo(AbsolutePath root) =>
      AbsolutePath(path).segmentRelativeTo(root);
}

extension EventExtensions on Event {
  /// The event [path] as an [AbsolutePath].
  AbsolutePath get absolutePath => AbsolutePath(path);

  /// The event [path] relative to [root].
  RelativePath pathRelativeTo(AbsolutePath root) =>
      AbsolutePath(path).relativeTo(root);

  /// Whether the event path parent directory is exactly [directory].
  bool isIn(AbsolutePath directory) => AbsolutePath(path).isIn(directory);
}

/// A relative file path.
extension type RelativePath(String _string) {
  List<PathSegment> get segments => _string.isEmpty
      ? const <PathSegment>[]
      : _string.split(Platform.pathSeparator) as List<PathSegment>;
}

/// A path segment.
extension type PathSegment._(String _string) implements RelativePath {
  factory PathSegment(String segment) {
    if (segment.isEmpty) throw ArgumentError('Segment cannot be empty.');
    if (segment.contains(Platform.pathSeparator)) {
      throw ArgumentError(
        'Segment cannot contain `${Platform.pathSeparator}`.',
        segment,
      );
    }
    return PathSegment._(segment);
  }
}
