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

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