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

/// A library for getting external source code links for Dartdoc.
library dartdoc.source_linker;

import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/model.dart';
import 'package:path/path.dart' as pathLib;

final uriTemplateRegexp = new RegExp(r'(%[frl]%)');

abstract class SourceLinkerOptionContext implements DartdocOptionContextBase {
  List<String> get linkToSourceExcludes =>
      optionSet['linkToSource']['excludes'].valueAt(context);
  String get linkToSourceRevision =>
      optionSet['linkToSource']['revision'].valueAt(context);
  String get linkToSourceRoot =>
      optionSet['linkToSource']['root'].valueAt(context);
  String get linkToSourceUriTemplate =>
      optionSet['linkToSource']['uriTemplate'].valueAt(context);
}

Future<List<DartdocOption>> createSourceLinkerOptions() async {
  return <DartdocOption>[
    new DartdocOptionSet('linkToSource')
      ..addAll([
        new DartdocOptionArgFile<List<String>>('excludes', [],
            isDir: true,
            help:
                'A list of directories to exclude from linking to a source code repository.'),
        // TODO(jcollins-g): Use [DartdocOptionArgSynth], possibly in combination with a repository type and the root directory, and get revision number automatically
        new DartdocOptionArgOnly<String>('revision', null,
            help: 'Revision number to insert into the URI.'),
        new DartdocOptionArgFile<String>('root', null,
            isDir: true,
            help:
                'Path to a local directory that is the root of the repository we link to.  All source code files under this directory will be linked.'),
        new DartdocOptionArgFile<String>('uriTemplate', null,
            help:
                '''Substitute into this template to generate a uri for an element's source code.
             Dartdoc dynamically substitutes the following fields into the template:
               %f%:  Relative path of file to the repository root
               %r%:  Revision number
               %l%:  Line number'''),
      ])
  ];
}

class SourceLinker {
  final List<String> excludes;
  final int lineNumber;
  final String sourceFileName;
  final String revision;
  final String root;
  final String uriTemplate;

  /// Most users of this class should use the [SourceLinker.fromElement] factory
  /// instead.  This constructor is public for testing.
  SourceLinker(
      {this.excludes,
      this.lineNumber,
      this.sourceFileName,
      this.revision,
      this.root,
      this.uriTemplate}) {
    assert(excludes != null, 'linkToSource excludes can not be null');
    if (revision != null || root != null || uriTemplate != null) {
      if (root == null || uriTemplate == null) {
        throw DartdocOptionError(
            'linkToSource root and uriTemplate must both be specified to generate repository links');
      }
      if (uriTemplate.contains('%r%') && revision == null) {
        throw DartdocOptionError(
            r'%r% specified in uriTemplate, but no revision available');
      }
    }
  }

  /// Build a SourceLinker from a ModelElement.
  factory SourceLinker.fromElement(ModelElement element) {
    SourceLinkerOptionContext config = element.config;
    return new SourceLinker(
      excludes: config.linkToSourceExcludes,
      // TODO(jcollins-g): disallow defaulting?  Some elements come back without
      // a line number right now.
      lineNumber: element.lineAndColumn?.item1 ?? 1,
      sourceFileName: element.sourceFileName,
      revision: config.linkToSourceRevision,
      root: config.linkToSourceRoot,
      uriTemplate: config.linkToSourceUriTemplate,
    );
  }

  String href() {
    if (sourceFileName == null || root == null || uriTemplate == null)
      return '';
    if (!pathLib.isWithin(root, sourceFileName) ||
        excludes
            .any((String exclude) => pathLib.isWithin(exclude, sourceFileName)))
      return '';
    return uriTemplate.replaceAllMapped(uriTemplateRegexp, (match) {
      switch (match[1]) {
        case '%f%':
          var urlContext = new pathLib.Context(style: pathLib.Style.url);
          return urlContext.joinAll(
              pathLib.split(pathLib.relative(sourceFileName, from: root)));
          break;
        case '%r%':
          return revision;
          break;
        case '%l%':
          return lineNumber.toString();
          break;
        default:
          return null;
      }
    });
  }
}
