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

/// Bazel support for protoc_plugin.
library;

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

import 'src/options.dart';
import 'src/output_config.dart';

/// Dart protoc plugin option for Bazel packages.
///
/// This option takes a semicolon-separated list of Bazel package metadata in
/// `package_name|input_root|output_root` form. `input_root` designates the
/// directory relative to which input protos are located -- typically the root
/// of the Bazel package, where the `BUILD` file is located. `output_root`
/// designates the directory relative to which generated `.pb.dart` outputs are
/// emitted -- typically the package's `lib/` directory under the genfiles
/// directory specified by `genfiles_dir` in the Bazel configuration. Generated
/// outputs are emitted at the same path relative to `output_root` as the input
/// proto is found relative to `input_root`.
///
/// For example, using `foo.bar|foo/bar|foo/bar/lib`:
///   * `foo/bar/baz.proto` will generate `foo/bar/lib/baz.pb.dart`
///   * `foo/bar/a/b/baz.proto` will generate `foo/bar/lib/a/b/baz.pb.dart`
const bazelOptionId = 'BazelPackages';

class BazelPackage {
  final String name;
  final String inputRoot;
  final String outputRoot;

  BazelPackage(this.name, String inputRoot, String outputRoot)
    : inputRoot = p.normalize(inputRoot),
      outputRoot = p.normalize(outputRoot);
}

/// Parser for the `BazelPackages` option.
class BazelOptionParser implements SingleOptionParser {
  /// Output map of package input_root to package.
  final Map<String, BazelPackage> output;

  BazelOptionParser(this.output);

  @override
  void parse(String name, String? value, OnError onError) {
    if (value == null) {
      onError('Invalid $bazelOptionId option. Expected a non-empty value.');
      return;
    }

    for (final entry in value.split(';')) {
      final fields = entry.split('|');
      if (fields.length != 3) {
        onError(
          'ERROR: expected package_name|input_root|output_root. Got: $entry',
        );
        continue;
      }
      final pkg = BazelPackage(fields[0], fields[1], fields[2]);
      if (!output.containsKey(pkg.inputRoot)) {
        output[pkg.inputRoot] = pkg;
      } else {
        final prev = output[pkg.inputRoot]!;
        if (pkg.name != prev.name) {
          onError(
            'ERROR: multiple packages with input_root ${pkg.inputRoot}: '
            '${prev.name} and ${pkg.name}',
          );
          continue;
        }
        if (pkg.outputRoot != prev.outputRoot) {
          onError(
            'ERROR: conflicting output_roots for package ${pkg.name}: '
            '${prev.outputRoot} and ${pkg.outputRoot}',
          );
          continue;
        }
      }
    }
  }
}

/// A Dart `package:` URI with package name and path components.
class _PackageUri {
  final String packageName;
  final String path;
  Uri get uri => Uri.parse('package:$packageName/$path');

  _PackageUri(this.packageName, this.path);
}

/// [OutputConfiguration] that uses Bazel layout information to resolve output
/// locations and imports.
class BazelOutputConfiguration extends DefaultOutputConfiguration {
  final Map<String, BazelPackage> packages;

  BazelOutputConfiguration(this.packages);

  /// Search for the most specific Bazel package above [searchPath].
  BazelPackage? _findPackage(String searchPath) {
    var index = searchPath.lastIndexOf('/');
    while (index > 0) {
      searchPath = searchPath.substring(0, index);
      final pkg = packages[searchPath];
      if (pkg != null) return pkg;
      index = searchPath.lastIndexOf('/');
    }
    return null;
  }

  @override
  Uri outputPathFor(Uri inputPath, String extension) {
    final pkg = _findPackage(inputPath.path);
    if (pkg == null) {
      throw ArgumentError('Unable to locate package for input $inputPath.');
    }

    // Bazel package-relative paths.
    final relativeInput = inputPath.path.substring('${pkg.inputRoot}/'.length);
    final base = p.withoutExtension(relativeInput);
    final outputPath = p.join(pkg.outputRoot, '$base$extension');
    return Uri.file(outputPath);
  }

  @override
  Uri resolveImport(Uri target, Uri source, String extension) {
    final targetBase = p.withoutExtension(target.path);
    final targetUri = _packageUriFor('$targetBase$extension');
    final sourceUri = _packageUriFor(source.path);

    if (targetUri == null && sourceUri != null) {
      // We can't reach outside of the lib/ directory of a package without
      // using a package: import. Using a relative import for [target] could
      // break anyone who uses a package: import to load [source].
      throw 'ERROR: cannot generate import for $target from $source.';
    }

    if (targetUri != null && sourceUri?.packageName != targetUri.packageName) {
      return targetUri.uri;
    }

    return super.resolveImport(target, source, extension);
  }

  _PackageUri? _packageUriFor(String target) {
    final pkg = _findPackage(target);
    if (pkg == null) return null;
    final relPath = target.substring(pkg.inputRoot.length + 1);
    return _PackageUri(pkg.name, relPath);
  }
}
