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

// This application generates markdown pages and screenshots for each
// sample app. For more information see ../README.md.

import 'dart:io';

import 'package:path/path.dart';

class SampleError extends Error {
  SampleError(this.message);
  final String message;
  @override
  String toString() => 'SampleError($message)';
}

// Sample apps are .dart files in the lib directory which contain a block
// comment that begins with a '/* Sample Catalog' line, and ends with a line
// that just contains '*/'. The following keywords may appear at the
// beginning of lines within the comment. A keyword's value is all of
// the following text up to the next keyword or the end of the comment,
// sans leading and trailing whitespace.
const String sampleCatalogKeywords = r'^Title:|^Summary:|^Description:|^Classes:|^Sample:|^See also:';

Directory outputDirectory;
Directory sampleDirectory;
Directory testDirectory;
Directory driverDirectory;

void logMessage(String s) { print(s); }
void logError(String s) { print(s); }

File inputFile(String dir, String name) {
  return File(dir + Platform.pathSeparator + name);
}

File outputFile(String name, [Directory directory]) {
  return File((directory ?? outputDirectory).path + Platform.pathSeparator + name);
}

void initialize() {
  outputDirectory = Directory('.generated');
  sampleDirectory = Directory('lib');
  testDirectory = Directory('test');
  driverDirectory = Directory('test_driver');
  outputDirectory.createSync();
}

// Return a copy of template with each occurrence of @(foo) replaced
// by values[foo].
String expandTemplate(String template, Map<String, String> values) {
  // Matches @(foo), match[1] == 'foo'
  final RegExp tokenRE = RegExp(r'@\(([\w ]+)\)', multiLine: true);
  return template.replaceAllMapped(tokenRE, (Match match) {
    if (match.groupCount != 1)
      throw SampleError('bad template keyword $match[0]');
    final String keyword = match[1];
    return values[keyword] ?? '';
  });
}

void writeExpandedTemplate(File output, String template, Map<String, String> values) {
  output.writeAsStringSync(expandTemplate(template, values));
  logMessage('wrote $output');
}

class SampleInfo {
  SampleInfo(this.sourceFile, this.commit);

  final File sourceFile;
  final String commit;
  String sourceCode;
  Map<String, String> commentValues;

  // If sourceFile is lib/foo.dart then sourceName is foo. The sourceName
  // is used to create derived filenames like foo.md or foo.png.
  String get sourceName => basenameWithoutExtension(sourceFile.path);

  // The website's link to this page will be /catalog/samples/@(link)/.
  String get link => sourceName.replaceAll('_', '-');

  // The name of the widget class that defines this sample app, like 'FooSample'.
  String get sampleClass => commentValues['sample'];

  // The value of the 'Classes:' comment as a list of class names.
  Iterable<String> get highlightedClasses {
    final String classNames = commentValues['classes'];
    if (classNames == null)
      return const <String>[];
    return classNames.split(',').map<String>((String s) => s.trim()).where((String s) => s.isNotEmpty);
  }

  // The relative import path for this sample, like '../lib/foo.dart'.
  String get importPath => '..' + Platform.pathSeparator + sourceFile.path;

  // Return true if we're able to find the "Sample Catalog" comment in the
  // sourceFile, and we're able to load its keyword/value pairs into
  // the commentValues Map. The rest of the file's contents are saved
  // in sourceCode.
  bool initialize() {
    final String contents = sourceFile.readAsStringSync();

    final RegExp startRE = RegExp(r'^/\*\s+^Sample\s+Catalog', multiLine: true);
    final RegExp endRE = RegExp(r'^\*/', multiLine: true);
    final Match startMatch = startRE.firstMatch(contents);
    if (startMatch == null)
      return false;

    final int startIndex = startMatch.end;
    final Match endMatch = endRE.firstMatch(contents.substring(startIndex));
    if (endMatch == null)
      return false;

    final String comment = contents.substring(startIndex, startIndex + endMatch.start);
    sourceCode = contents.substring(0, startMatch.start) + contents.substring(startIndex + endMatch.end);
    if (sourceCode.trim().isEmpty)
      throw SampleError('did not find any source code in $sourceFile');

    final RegExp keywordsRE = RegExp(sampleCatalogKeywords, multiLine: true);
    final List<Match> keywordMatches = keywordsRE.allMatches(comment).toList();
    if (keywordMatches.isEmpty)
      throw SampleError('did not find any keywords in the Sample Catalog comment in $sourceFile');

    commentValues = <String, String>{};
    for (int i = 0; i < keywordMatches.length; i += 1) {
      final String keyword = comment.substring(keywordMatches[i].start, keywordMatches[i].end - 1);
      final String value = comment.substring(
        keywordMatches[i].end,
        i == keywordMatches.length - 1 ? null : keywordMatches[i + 1].start,
      );
      commentValues[keyword.toLowerCase()] = value.trim();
    }
    commentValues['name'] = sourceName;
    commentValues['path'] = 'examples/catalog/${sourceFile.path}';
    commentValues['source'] = sourceCode.trim();
    commentValues['link'] = link;
    commentValues['android screenshot'] = 'https://storage.googleapis.com/flutter-catalog/$commit/${sourceName}_small.png';

    return true;
  }
}

void generate(String commit) {
  initialize();

  final List<SampleInfo> samples = <SampleInfo>[];
  for (final FileSystemEntity entity in sampleDirectory.listSync()) {
    if (entity is File && entity.path.endsWith('.dart')) {
      final SampleInfo sample = SampleInfo(entity, commit);
      if (sample.initialize()) // skip files that lack the Sample Catalog comment
        samples.add(sample);
    }
  }

  // Causes the generated imports to appear in alphabetical order.
  // Avoid complaints from flutter lint.
  samples.sort((SampleInfo a, SampleInfo b) {
    return a.sourceName.compareTo(b.sourceName);
  });

  final String entryTemplate = inputFile('bin', 'entry.md.template').readAsStringSync();

  // Write the sample catalog's home page: index.md
  final Iterable<String> entries = samples.map<String>((SampleInfo sample) {
    return expandTemplate(entryTemplate, sample.commentValues);
  });
  writeExpandedTemplate(
    outputFile('index.md'),
    inputFile('bin', 'index.md.template').readAsStringSync(),
    <String, String>{
      'entries': entries.join('\n'),
    },
  );

  // Write the sample app files, like animated_list.md
  for (final SampleInfo sample in samples) {
    writeExpandedTemplate(
      outputFile(sample.sourceName + '.md'),
      inputFile('bin', 'sample_page.md.template').readAsStringSync(),
      sample.commentValues,
    );
  }

  // For each unique class listened in a sample app's "Classes:" list, generate
  // a file that's structurally the same as index.md but only contains samples
  // that feature one class. For example AnimatedList_index.md would only
  // include samples that had AnimatedList in their "Classes:" list.
  final Map<String, List<SampleInfo>> classToSamples = <String, List<SampleInfo>>{};
  for (final SampleInfo sample in samples) {
    for (final String className in sample.highlightedClasses) {
      classToSamples[className] ??= <SampleInfo>[];
      classToSamples[className].add(sample);
    }
  }
  for (final String className in classToSamples.keys) {
    final Iterable<String> entries = classToSamples[className].map<String>((SampleInfo sample) {
      return expandTemplate(entryTemplate, sample.commentValues);
    });
    writeExpandedTemplate(
      outputFile('${className}_index.md'),
      inputFile('bin', 'class_index.md.template').readAsStringSync(),
      <String, String>{
        'class': className,
        'entries': entries.join('\n'),
        'link': '${className}_index',
      },
    );
  }

  // Write screenshot.dart, a "test" app that displays each sample
  // app in turn when the app is tapped.
  writeExpandedTemplate(
    outputFile('screenshot.dart', driverDirectory),
    inputFile('bin', 'screenshot.dart.template').readAsStringSync(),
    <String, String>{
      'imports': samples.map<String>((SampleInfo page) {
        return "import '${page.importPath}' show ${page.sampleClass};\n";
      }).join(),
      'widgets': samples.map<String>((SampleInfo sample) {
        return 'new ${sample.sampleClass}(),\n';
      }).join(),
    },
  );

  // Write screenshot_test.dart, a test driver for screenshot.dart
  // that collects screenshots of each app and saves them.
  writeExpandedTemplate(
    outputFile('screenshot_test.dart', driverDirectory),
    inputFile('bin', 'screenshot_test.dart.template').readAsStringSync(),
    <String, String>{
      'paths': samples.map<String>((SampleInfo sample) {
        return "'${outputFile(sample.sourceName + '.png').path}'";
      }).join(',\n'),
    },
  );

  // For now, the website's index.json file must be updated by hand.
  logMessage('The following entries must appear in _data/catalog/widgets.json');
  for (final String className in classToSamples.keys)
    logMessage('"sample": "${className}_index"');
}

void main(List<String> args) {
  if (args.length != 1) {
    logError(
      'Usage (cd examples/catalog/; dart bin/sample_page.dart commit)\n'
      'The flutter commit hash locates screenshots on storage.googleapis.com/flutter-catalog/'
    );
    exit(255);
  }
  try {
    generate(args[0]);
  } catch (error) {
    logError(
      'Error: sample_page.dart failed: $error\n'
      'This sample_page.dart app expects to be run from the examples/catalog directory. '
      'More information can be found in examples/catalog/README.md.'
    );
    exit(255);
  }
  exit(0);
}
