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

    // DartPad only supports stable or master as valid channels. Use master
    // if not on stable so that local runs will work (although they will
    // still take their sample code from the master docs server).
    final String channel = metadata['channel'] == 'stable' ? 'stable' : 'master';

    final Map<String, String> substitutions = <String, String>{
      'description': description,
      'code': htmlEscape.convert(result.join('\n')),
      'language': language ?? 'dart',
      'serial': '',
      'id': metadata['id'] as String,
      'channel': channel,
      '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);
        if (components.isNotEmpty) {
          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 samples 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.addAll(<String, Object>{
          '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);
  }
}
