// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:dart_style/dart_style.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import 'configuration.dart';

void errorExit(String message) {
  stderr.writeln(message);
  exit(1);
}

// A Tuple containing the name and contents associated with a code block in a
// snippet.
class _ComponentTuple {
  _ComponentTuple(this.name, this.contents, {String language}) : language = language ?? '';
  final String name;
  final List<String> contents;
  final String language;
  String get mergedContent => contents.join('\n').trim();
}

/// Generates the snippet HTML, as well as saving the output snippet main to
/// the output directory.
class SnippetGenerator {
  SnippetGenerator({Configuration configuration})
      : configuration = configuration ??
            // Flutter's root is four directories up from this script.
            Configuration(flutterRoot: Directory(Platform.environment['FLUTTER_ROOT']
                ?? path.canonicalize(path.join(path.dirname(path.fromUri(Platform.script)), '..', '..', '..')))) {
    this.configuration.createOutputDirectory();
  }

  /// The configuration used to determine where to get/save data for the
  /// snippet.
  final Configuration configuration;

  static const JsonEncoder jsonEncoder = JsonEncoder.withIndent('    ');

  /// A Dart formatted used to format the snippet code and finished application
  /// code.
  static DartFormatter formatter = DartFormatter(pageWidth: 80, fixes: StyleFix.all);

  /// This returns the output file for a given snippet ID. Only used for
  /// [SnippetType.sample] snippets.
  File getOutputFile(String id) => File(path.join(configuration.outputDirectory.path, '$id.dart'));

  /// Gets the path to the template file requested.
  File getTemplatePath(String templateName, {Directory templatesDir}) {
    final Directory templateDir = templatesDir ?? configuration.templatesDirectory;
    final File templateFile = File(path.join(templateDir.path, '$templateName.tmpl'));
    return templateFile.existsSync() ? templateFile : null;
  }

  /// Injects the [injections] into the [template], and turning the
  /// "description" injection into a comment. Only used for
  /// [SnippetType.sample] snippets.
  String interpolateTemplate(List<_ComponentTuple> injections, String template, Map<String, Object> metadata) {
    final RegExp moustacheRegExp = RegExp('{{([^}]+)}}');
    return template.replaceAllMapped(moustacheRegExp, (Match match) {
      if (match[1] == 'description') {
        // Place the description into a comment.
        final List<String> description = injections
            .firstWhere((_ComponentTuple tuple) => tuple.name == match[1])
            .contents
            .map<String>((String line) => '// $line')
            .toList();
        // Remove any leading/trailing empty comment lines.
        // We don't want to remove ALL empty comment lines, only the ones at the
        // beginning and the end.
        while (description.isNotEmpty && description.last == '// ') {
          description.removeLast();
        }
        while (description.isNotEmpty && description.first == '// ') {
          description.removeAt(0);
        }
        return description.join('\n').trim();
      } else {
        // If the match isn't found in the injections, then just remove the
        // mustache reference, since we want to allow the sections to be
        // "optional" in the input: users shouldn't be forced to add an empty
        // "```dart preamble" section if that section would be empty.
        final _ComponentTuple result = injections
            .firstWhere((_ComponentTuple tuple) => tuple.name == match[1], orElse: () => null);
        return result?.mergedContent ?? (metadata[match[1]] ?? '').toString();
      }
    }).trim();
  }

  /// Interpolates the [injections] into an HTML skeleton file.
  ///
  /// Similar to interpolateTemplate, but we are only looking for `code-`
  /// components, and we care about the order of the injections.
  ///
  /// Takes into account the [type] and doesn't substitute in the id and the app
  /// if not a [SnippetType.sample] snippet.
  String interpolateSkeleton(SnippetType type, List<_ComponentTuple> injections, String skeleton, Map<String, Object> metadata) {
    final List<String> result = <String>[];
    const HtmlEscape htmlEscape = HtmlEscape();
    String language;
    for (final _ComponentTuple injection in injections) {
      if (!injection.name.startsWith('code')) {
        continue;
      }
      result.addAll(injection.contents);
      if (injection.language.isNotEmpty) {
        language = injection.language;
      }
      result.addAll(<String>['', '// ...', '']);
    }
    if (result.length > 3) {
      result.removeRange(result.length - 3, result.length);
    }
    // Only insert a div for the description if there actually is some text there.
    // This means that the {{description}} marker in the skeleton needs to
    // be inside of an {@inject-html} block.
    String description = injections.firstWhere((_ComponentTuple tuple) => tuple.name == 'description').mergedContent;
    description = description.trim().isNotEmpty
        ? '<div class="snippet-description">{@end-inject-html}$description{@inject-html}</div>'
        : '';
    final Map<String, String> substitutions = <String, String>{
      'description': description,
      'code': htmlEscape.convert(result.join('\n')),
      'language': language ?? 'dart',
      'serial': '',
      'id': metadata['id'] as String,
      'element': metadata['element'] as String ?? '',
      'app': '',
    };
    if (type == SnippetType.sample) {
      substitutions
        ..['serial'] = metadata['serial']?.toString() ?? '0'
        ..['app'] = htmlEscape.convert(injections.firstWhere((_ComponentTuple tuple) => tuple.name == 'app').mergedContent);
    }
    return skeleton.replaceAllMapped(RegExp('{{(${substitutions.keys.join('|')})}}'), (Match match) {
      return substitutions[match[1]];
    });
  }

  /// Parses the input for the various code and description segments, and
  /// returns them in the order found.
  List<_ComponentTuple> parseInput(String input) {
    bool inCodeBlock = false;
    input = input.trim();
    final List<String> description = <String>[];
    final List<_ComponentTuple> components = <_ComponentTuple>[];
    String language;
    final RegExp codeStartEnd = RegExp(r'^\s*```([-\w]+|[-\w]+ ([-\w]+))?\s*$');
    for (final String line in input.split('\n')) {
      final Match match = codeStartEnd.firstMatch(line);
      if (match != null) { // If we saw the start or end of a code block
        inCodeBlock = !inCodeBlock;
        if (match[1] != null) {
          language = match[1];
          if (match[2] != null) {
            components.add(_ComponentTuple('code-${match[2]}', <String>[], language: language));
          } else {
            components.add(_ComponentTuple('code', <String>[], language: language));
          }
        } else {
          language = null;
        }
        continue;
      }
      if (!inCodeBlock) {
        description.add(line);
      } else {
        assert(language != null);
        components.last.contents.add(line);
      }
    }
    return <_ComponentTuple>[
      _ComponentTuple('description', description),
      ...components,
    ];
  }

  String _loadFileAsUtf8(File file) {
    return file.readAsStringSync(encoding: Encoding.getByName('utf-8'));
  }

  String _addLineNumbers(String app) {
    final StringBuffer buffer = StringBuffer();
    int count = 0;
    for (final String line in app.split('\n')) {
      count++;
      buffer.writeln('${count.toString().padLeft(5, ' ')}: $line');
    }
    return buffer.toString();
  }

  /// The main routine for generating snippets.
  ///
  /// The [input] is the file containing the dartdoc comments (minus the leading
  /// comment markers).
  ///
  /// The [type] is the type of snippet to create: either a
  /// [SnippetType.sample] or a [SnippetType.snippet].
  ///
  /// [showDartPad] indicates whether DartPad should be shown where possible.
  /// Currently, this value only has an effect if [type] is
  /// [SnippetType.sample], in which case an alternate skeleton file is
  /// used to create the final HTML output.
  ///
  /// The [template] must not be null if the [type] is
  /// [SnippetType.sample], and specifies the name of the template to use
  /// for the application code.
  ///
  /// The [id] is a string ID to use for the output file, and to tell the user
  /// about in the `flutter create` hint. It must not be null if the [type] is
  /// [SnippetType.sample].
  String generate(
    File input,
    SnippetType type, {
    bool showDartPad = false,
    String template,
    File output,
    @required Map<String, Object> metadata,
  }) {
    assert(template != null || type != SnippetType.sample);
    assert(metadata != null && metadata['id'] != null);
    assert(input != null);
    assert(!showDartPad || type == SnippetType.sample,
        'Only application snippets work with dartpad.');
    final List<_ComponentTuple> snippetData = parseInput(_loadFileAsUtf8(input));
    switch (type) {
      case SnippetType.sample:
        final Directory templatesDir = configuration.templatesDirectory;
        if (templatesDir == null) {
          stderr.writeln('Unable to find the templates directory.');
          exit(1);
        }
        final File templateFile = getTemplatePath(template, templatesDir: templatesDir);
        if (templateFile == null) {
          stderr.writeln(
              'The template $template was not found in the templates directory ${templatesDir.path}');
          exit(1);
        }
        final String templateContents = _loadFileAsUtf8(templateFile);
        String app = interpolateTemplate(snippetData, templateContents, metadata);

        try {
          app = formatter.format(app);
        } on FormatterException catch (exception) {
          stderr.write('Code to format:\n${_addLineNumbers(app)}\n');
          errorExit('Unable to format snippet app template: $exception');
        }

        snippetData.add(_ComponentTuple('app', app.split('\n')));
        final File outputFile = output ?? getOutputFile(metadata['id'] as String);
        stderr.writeln('Writing to ${outputFile.absolute.path}');
        outputFile.writeAsStringSync(app);

        final File metadataFile = File(path.join(path.dirname(outputFile.path),
            '${path.basenameWithoutExtension(outputFile.path)}.json'));
        stderr.writeln('Writing metadata to ${metadataFile.absolute.path}');
        final _ComponentTuple description = snippetData.firstWhere(
          (_ComponentTuple data) => data.name == 'description',
          orElse: () => null,
        );
        metadata ??= <String, Object>{};
        metadata.addAll(<String, Object>{
          'id': metadata['id'],
          'file': path.basename(outputFile.path),
          'description': description?.mergedContent,
        });
        metadataFile.writeAsStringSync(jsonEncoder.convert(metadata));
        break;
      case SnippetType.snippet:
        break;
    }
    final String skeleton =
        _loadFileAsUtf8(configuration.getHtmlSkeletonFile(type, showDartPad: showDartPad));
    return interpolateSkeleton(type, snippetData, skeleton, metadata);
  }
}
