// 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 protoc_bazel;

import 'package:path/path.dart' as p;
import 'protoc.dart'
    show SingleOptionParser, DefaultOutputConfiguration, OnError;

/// 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 input_root;
  final String output_root;

  BazelPackage(this.name, String input_root, String output_root)
      : input_root = p.normalize(input_root),
        output_root = p.normalize(output_root);
}

/// 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 (var entry in value.split(';')) {
      var fields = entry.split('|');
      if (fields.length != 3) {
        onError(
            'ERROR: expected package_name|input_root|output_root. Got: $entry');
        continue;
      }
      var pkg = BazelPackage(fields[0], fields[1], fields[2]);
      if (!output.containsKey(pkg.input_root)) {
        output[pkg.input_root] = pkg;
      } else {
        var prev = output[pkg.input_root];
        if (pkg.name != prev.name) {
          onError('ERROR: multiple packages with input_root ${pkg.input_root}: '
              '${prev.name} and ${pkg.name}');
          continue;
        }
        if (pkg.output_root != prev.output_root) {
          onError('ERROR: conflicting output_roots for package ${pkg.name}: '
              '${prev.output_root} and ${pkg.output_root}');
          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);
      var pkg = packages[searchPath];
      if (pkg != null) return pkg;
      index = searchPath.lastIndexOf('/');
    }
    return null;
  }

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

    // Bazel package-relative paths.
    var relativeInput = input.path.substring('${pkg.input_root}/'.length);
    var base = p.withoutExtension(relativeInput);
    var outputPath = p.join(pkg.output_root, "$base$extension");
    return Uri.file(outputPath);
  }

  @override
  Uri resolveImport(Uri target, Uri source, String extension) {
    var targetBase = p.withoutExtension(target.path);
    var targetUri = _packageUriFor("$targetBase$extension");
    var 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) {
    var pkg = _findPackage(target);
    if (pkg == null) return null;
    var relPath = target.substring(pkg.input_root.length + 1);
    return _PackageUri(pkg.name, relPath);
  }
}
