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

/// 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(String message)) {
    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);
  }
}
