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

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';

PSEntry? _findEntry(
    YamlMap map, String key, ResourceProvider? resourceProvider) {
  PSEntry? entry;
  map.nodes.forEach((k, v) {
    if (k is YamlScalar && key == k.toString()) {
      entry = _processScalar(k, v, resourceProvider);
    }
  });
  return entry;
}

PSDependencyList? _processDependencies(
    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
  if (v is! YamlMap) {
    return null;
  }
  YamlMap depsMap = v;

  _PSDependencyList deps = _PSDependencyList(_PSNode(key, resourceProvider));
  depsMap.nodes.forEach((k, v) {
    if (k is YamlScalar) deps.add(_PSDependency(k, v, resourceProvider));
  });
  return deps;
}

PSGitRepo? _processGitRepo(
    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
  if (v is YamlScalar) {
    _PSGitRepo repo = _PSGitRepo();
    repo.token = _PSNode(key, resourceProvider);
    repo.url = PSEntry(repo.token, _PSNode(v, resourceProvider));
    return repo;
  }
  if (v is! YamlMap) {
    return null;
  }
  YamlMap hostMap = v;
  // url: git://github.com/munificent/kittens.git
  // ref: some-branch
  _PSGitRepo repo = _PSGitRepo();
  repo.token = _PSNode(key, resourceProvider);
  repo.ref = _findEntry(hostMap, 'ref', resourceProvider);
  repo.url = _findEntry(hostMap, 'url', resourceProvider);
  return repo;
}

PSHost? _processHost(
    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
  if (v is YamlScalar) {
    // dependencies:
    //   mypkg:
    //     hosted:  https://some-pub-server.com
    //     version: ^1.2.3
    _PSHost host = _PSHost(isShortForm: true);
    host.token = _PSNode(key, resourceProvider);
    host.url = _processScalar(key, v, resourceProvider);
    return host;
  }
  if (v is YamlMap) {
    YamlMap hostMap = v;
    // name: transmogrify
    // url: http://your-package-server.com
    _PSHost host = _PSHost(isShortForm: false);
    host.token = _PSNode(key, resourceProvider);
    host.name = _findEntry(hostMap, 'name', resourceProvider);
    host.url = _findEntry(hostMap, 'url', resourceProvider);
    return host;
  }
  return null;
}

PSEntry? _processScalar(
    YamlScalar key, YamlNode value, ResourceProvider? resourceProvider) {
  if (value is! YamlScalar) {
    return null;
    //WARN?
  }
  return PSEntry(
      _PSNode(key, resourceProvider), _PSNode(value, resourceProvider));
}

PSNodeList? _processScalarList(
    YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
  if (v is! YamlList) {
    return null;
  }
  YamlList nodeList = v;

  return _PSNodeList(
      _PSNode(key, resourceProvider),
      nodeList.nodes
          .whereType<YamlScalar>()
          .map((n) => _PSNode(n, resourceProvider)));
}

/// Representation of a key/value pair a map from package name to
/// _package description_.
///
/// **Example** of a path-dependency:
/// ```yaml
/// dependencies:
///   <name>:
///     version: <version>
///     path: <path>
/// ```
abstract class PSDependency {
  PSGitRepo? get git;
  PSHost? get host;
  PSNode? get name;
  PSEntry? get path;
  PSEntry? get version;
}

/// Representation of the map from package name to _package description_ used
/// under `dependencies`, `dev_dependencies` and `dependency_overrides`.
abstract class PSDependencyList with IterableMixin<PSDependency> {}

class PSEntry {
  final PSNode? key;
  final PSNode value;
  PSEntry(this.key, this.value);

  @override
  String toString() => '${key != null ? (key.toString() + ': ') : ''}$value';
}

/// Representation of git-dependency in `pubspec.yaml`.
///
/// **Example** of a git-dependency:
/// ```yaml
/// dependencies:
///   foo:
///     git: # <-- this is the [token] property
///       url: https://github.com/example/example
///       ref: main # ref is optional
/// ```
///
/// This may also be written in the form:
/// ```yaml
/// dependencies:
///   foo:
///     git:       https://github.com/example/example
///     # ^-token  ^--url
///     # In this case [ref] is `null`.
/// ```
abstract class PSGitRepo {
  /// [PSEntry] for `ref: main` where [PSEntry.key] is `ref` and [PSEntry.value]
  /// is `main`.
  PSEntry? get ref;

  /// The `'git'` from the `pubspec.yaml`, this is the key that indicates this
  /// is a git-dependency.
  PSNode? get token;

  /// [PSEntry] for `url: https://...` or `git: https://`, where [PSEntry.key]
  /// is either `url` or `git`, and [PSEntry.key] is the URL.
  ///
  /// If the git-dependency is given in the form:
  /// ```yaml
  /// dependencies:
  ///   foo:
  ///     git:       https://github.com/example/example
  /// ```
  /// Then [token] and [url.key] will be the same object.
  PSEntry? get url;
}

abstract class PSHost {
  /// True, if _short-form_ for writing hosted-dependencies was used.
  ///
  /// **Example** of a hosted-dependency written in short-form:
  /// ```yaml
  /// dependencies:
  ///   foo:
  ///     hosted: https://some-pub-server.com
  ///     version: ^1.2.3
  /// ```
  ///
  /// The _long-form_ for writing the dependency given above is:
  /// ```yaml
  /// dependencies:
  ///   foo:
  ///     hosted:
  ///       url: https://some-pub-server.com
  ///       name: foo
  ///     version: ^1.2.3
  /// ```
  ///
  /// The short-form was added in Dart 2.15.0 because:
  ///  * The `name` property just specifies the package name, which can be
  ///    inferred from the context. So it is unnecessary to write it.
  ///  * The nested object and `url` key becomes unnecessary when the `name`
  ///    property is removed.
  bool get isShortForm;

  PSEntry? get name;
  PSNode? get token;
  PSEntry? get url;
}

/// Representation of a leaf-node from `pubspec.yaml`.
abstract class PSNode {
  Source get source;
  SourceSpan get span;

  /// String value of the node, or `null` if value in pubspec.yaml is `null` or
  /// omitted.
  ///
  /// **Example**
  /// ```
  /// name: foo
  /// version:
  /// ```
  /// In the example above the [PSNode] for `foo` will have [text] "foo", and
  /// the [PSNode] for `version` will have not have [text] as `null`, as empty
  /// value or `"null"` is the same in YAML.
  String? get text;
}

abstract class PSNodeList with IterableMixin<PSNode> {
  @override
  Iterator<PSNode> get iterator;
  PSNode get token;
}

abstract class Pubspec {
  factory Pubspec.parse(String source,
          {Uri? sourceUrl, ResourceProvider? resourceProvider}) =>
      _Pubspec(source,
          sourceUrl: sourceUrl, resourceProvider: resourceProvider);
  PSEntry? get author;
  PSNodeList? get authors;
  PSDependencyList? get dependencies;
  PSDependencyList? get dependencyOverrides;
  PSEntry? get description;
  PSDependencyList? get devDependencies;
  PSEntry? get documentation;
  PSEntry? get homepage;
  PSEntry? get issueTracker;
  PSEntry? get name;
  PSEntry? get repository;
  PSEntry? get version;
  void accept(PubspecVisitor visitor);
}

abstract class PubspecVisitor<T> {
  T? visitPackageAuthor(PSEntry author) => null;
  T? visitPackageAuthors(PSNodeList authors) => null;
  T? visitPackageDependencies(PSDependencyList dependencies) => null;
  T? visitPackageDependency(PSDependency dependency) => null;
  T? visitPackageDependencyOverride(PSDependency dependency) => null;
  T? visitPackageDependencyOverrides(PSDependencyList dependencies) => null;
  T? visitPackageDescription(PSEntry description) => null;
  T? visitPackageDevDependencies(PSDependencyList dependencies) => null;
  T? visitPackageDevDependency(PSDependency dependency) => null;
  T? visitPackageDocumentation(PSEntry documentation) => null;
  T? visitPackageHomepage(PSEntry homepage) => null;
  T? visitPackageIssueTracker(PSEntry issueTracker) => null;
  T? visitPackageName(PSEntry name) => null;
  T? visitPackageRepository(PSEntry repostory) => null;
  T? visitPackageVersion(PSEntry version) => null;
}

class _PSDependency extends PSDependency {
  @override
  PSNode? name;
  @override
  PSEntry? path;
  @override
  PSEntry? version;
  @override
  PSHost? host;
  @override
  PSGitRepo? git;

  factory _PSDependency(
      YamlScalar key, YamlNode value, ResourceProvider? resourceProvider) {
    _PSDependency dep = _PSDependency._();

    dep.name = _PSNode(key, resourceProvider);

    if (value is YamlScalar) {
      // Simple version
      dep.version = PSEntry(null, _PSNode(value, resourceProvider));
    } else if (value is YamlMap) {
      // hosted:
      //   name: transmogrify
      //   url: http://your-package-server.com
      //   version: '>=0.4.0 <1.0.0'
      YamlMap details = value;
      details.nodes.forEach((k, v) {
        if (k is! YamlScalar) {
          return;
        }
        YamlScalar key = k;
        switch (key.toString()) {
          case 'path':
            dep.path = _processScalar(key, v, resourceProvider);
            break;
          case 'version':
            dep.version = _processScalar(key, v, resourceProvider);
            break;
          case 'hosted':
            dep.host = _processHost(key, v, resourceProvider);
            break;
          case 'git':
            dep.git = _processGitRepo(key, v, resourceProvider);
            break;
        }
      });
    }
    return dep;
  }

  _PSDependency._();

  @override
  String toString() {
    var sb = StringBuffer();
    if (name != null) {
      sb.write('$name:');
    }
    var versionInfo = '';
    if (version != null) {
      if (version!.key == null) {
        versionInfo = ' $version';
      } else {
        versionInfo = '\n    $version';
      }
    }
    sb.writeln(versionInfo);
    if (host != null) {
      sb.writeln(host);
    }
    if (git != null) {
      sb.writeln(git);
    }
    return sb.toString();
  }
}

class _PSDependencyList extends PSDependencyList {
  final dependencies = <PSDependency>[];
  final PSNode token;

  _PSDependencyList(this.token);

  @override
  Iterator<PSDependency> get iterator => dependencies.iterator;

  void add(PSDependency? dependency) {
    if (dependency != null) {
      dependencies.add(dependency);
    }
  }

  @override
  String toString() => '$token\n${dependencies.join('  ')}';
}

class _PSGitRepo implements PSGitRepo {
  @override
  PSNode? token;
  @override
  PSEntry? ref;
  @override
  PSEntry? url;
  @override
  String toString() => '''
    $token:
      $url
      $ref''';
}

class _PSHost implements PSHost {
  @override
  bool isShortForm;

  @override
  PSEntry? name;

  @override
  PSNode? token;

  @override
  PSEntry? url;

  _PSHost({required this.isShortForm});

  @override
  String toString() => '''
    $token:
      $name
      $url''';
}

class _PSNode implements PSNode {
  @override
  final String? text;
  @override
  final SourceSpan span;

  final ResourceProvider? resourceProvider;

  _PSNode(YamlScalar node, this.resourceProvider)
      : text = node.value?.toString(),
        span = node.span;

  @override
  Source get source => (resourceProvider ?? PhysicalResourceProvider.INSTANCE)
      .getFile(span.sourceUrl!.toFilePath())
      .createSource(span.sourceUrl);

  @override
  String toString() => '$text';
}

class _PSNodeList extends PSNodeList {
  @override
  final PSNode token;
  final Iterable<PSNode> nodes;

  _PSNodeList(this.token, this.nodes);

  @override
  Iterator<PSNode> get iterator => nodes.iterator;

  @override
  String toString() => '''
$token:
  - ${nodes.join('\n  - ')}''';
}

class _Pubspec implements Pubspec {
  @override
  PSEntry? author;
  @override
  PSNodeList? authors;
  @override
  PSEntry? description;
  @override
  PSEntry? documentation;
  @override
  PSEntry? homepage;
  @override
  PSEntry? issueTracker;
  @override
  PSEntry? name;
  @override
  PSEntry? repository;
  @override
  PSEntry? version;
  @override
  PSDependencyList? dependencies;
  @override
  PSDependencyList? devDependencies;
  @override
  PSDependencyList? dependencyOverrides;

  _Pubspec(String src, {Uri? sourceUrl, ResourceProvider? resourceProvider}) {
    try {
      _parse(src, sourceUrl: sourceUrl, resourceProvider: resourceProvider);
    } on Exception {
      // ignore
    }
  }

  @override
  void accept(PubspecVisitor visitor) {
    if (author != null) {
      visitor.visitPackageAuthor(author!);
    }
    if (authors != null) {
      visitor.visitPackageAuthors(authors!);
    }
    if (description != null) {
      visitor.visitPackageDescription(description!);
    }
    if (documentation != null) {
      visitor.visitPackageDocumentation(documentation!);
    }
    if (homepage != null) {
      visitor.visitPackageHomepage(homepage!);
    }
    if (issueTracker != null) {
      visitor.visitPackageIssueTracker(issueTracker!);
    }
    if (repository != null) {
      visitor.visitPackageRepository(repository!);
    }
    if (name != null) {
      visitor.visitPackageName(name!);
    }
    if (version != null) {
      visitor.visitPackageVersion(version!);
    }
    if (dependencies != null) {
      visitor.visitPackageDependencies(dependencies!);
      dependencies!.forEach(visitor.visitPackageDependency);
    }
    if (devDependencies != null) {
      visitor.visitPackageDevDependencies(devDependencies!);
      devDependencies!.forEach(visitor.visitPackageDevDependency);
    }
    if (dependencyOverrides != null) {
      visitor.visitPackageDependencyOverrides(dependencyOverrides!);
      dependencyOverrides!.forEach(visitor.visitPackageDependencyOverride);
    }
  }

  @override
  String toString() {
    var sb = _StringBuilder();
    sb.writelin(name);
    sb.writelin(version);
    sb.writelin(author);
    sb.writelin(authors);
    sb.writelin(description);
    sb.writelin(homepage);
    sb.writelin(repository);
    sb.writelin(issueTracker);
    sb.writelin(dependencies);
    sb.writelin(devDependencies);
    sb.writelin(dependencyOverrides);
    return sb.toString();
  }

  void _parse(String src,
      {Uri? sourceUrl, ResourceProvider? resourceProvider}) {
    var yaml = loadYamlNode(src, sourceUrl: sourceUrl);
    if (yaml is! YamlMap) {
      return;
    }
    YamlMap yamlMap = yaml;
    yamlMap.nodes.forEach((k, v) {
      if (k is! YamlScalar) {
        return;
      }
      YamlScalar key = k;
      switch (key.toString()) {
        case 'author':
          author = _processScalar(key, v, resourceProvider);
          break;
        case 'authors':
          authors = _processScalarList(key, v, resourceProvider);
          break;
        case 'homepage':
          homepage = _processScalar(key, v, resourceProvider);
          break;
        case 'repository':
          repository = _processScalar(key, v, resourceProvider);
          break;
        case 'issue_tracker':
          issueTracker = _processScalar(key, v, resourceProvider);
          break;
        case 'name':
          name = _processScalar(key, v, resourceProvider);
          break;
        case 'description':
          description = _processScalar(key, v, resourceProvider);
          break;
        case 'documentation':
          documentation = _processScalar(key, v, resourceProvider);
          break;
        case 'dependencies':
          dependencies = _processDependencies(key, v, resourceProvider);
          break;
        case 'dev_dependencies':
          devDependencies = _processDependencies(key, v, resourceProvider);
          break;
        case 'dependency_overrides':
          dependencyOverrides = _processDependencies(key, v, resourceProvider);
          break;
        case 'version':
          version = _processScalar(key, v, resourceProvider);
          break;
      }
    });
  }
}

class _StringBuilder {
  StringBuffer buffer = StringBuffer();
  @override
  String toString() => buffer.toString();
  void writelin(Object? value) {
    if (value != null) {
      buffer.writeln(value);
    }
  }
}
