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

import 'dart:io';

import 'package:markdown/markdown.dart';
import 'package:path/path.dart';
import 'package:pub_semver/pub_semver.dart';

import 'common/generate_common.dart';
import 'dart/generate_dart.dart' as dart show Api, api, DartGenerator;
import 'java/generate_java.dart' as java show Api, api, JavaGenerator;

final bool _stampPubspecVersion = false;

/// Parse the 'service.md' into a model and generate both Dart and Java
/// libraries.
main(List<String> args) async {
  String appDirPath = dirname(Platform.script.toFilePath());

  // Parse service.md into a model.
  var file = new File(
      normalize(join(appDirPath, '../../../runtime/vm/service/service.md')));
  var document = new Document();
  StringBuffer buf = new StringBuffer(file.readAsStringSync());
  var nodes = document.parseLines(buf.toString().split('\n'));
  print('Parsed ${file.path}.');
  print('Service protocol version ${ApiParseUtil.parseVersionString(nodes)}.');

  // Generate code from the model.
  print('');

  await _generateDart(appDirPath, nodes);
  await _generateJava(appDirPath, nodes);
  await _generateAsserts(appDirPath, nodes);
}

_generateDart(String appDirPath, List<Node> nodes) async {
  var outDirPath = normalize(join(appDirPath, '..', 'lib'));
  var outDir = new Directory(outDirPath);
  if (!outDir.existsSync()) outDir.createSync(recursive: true);
  var outputFile = new File(join(outDirPath, 'vm_service.dart'));
  var generator = new dart.DartGenerator();
  dart.api = new dart.Api();
  dart.api.parse(nodes);
  dart.api.generate(generator);
  outputFile.writeAsStringSync(generator.toString());
  Process.runSync('dartfmt', ['-w', outDirPath]);

  if (_stampPubspecVersion) {
    // Update the pubspec file.
    Version version = ApiParseUtil.parseVersionSemVer(nodes);
    _stampPubspec(version);

    // Validate that the changelog contains an entry for the current version.
    _checkUpdateChangelog(version);
  }

  print('Wrote Dart to ${outputFile.path}.');
}

_generateJava(String appDirPath, List<Node> nodes) async {
  var srcDirPath = normalize(join(appDirPath, '..', 'java', 'src'));
  var generator = new java.JavaGenerator(srcDirPath);
  java.api = new java.Api();
  java.api.parse(nodes);
  java.api.generate(generator);

  // We generate files into the java/src/ folder; ensure the generated files
  // aren't committed to git (but manually maintained files in the same
  // directory are).
  List<String> generatedPaths = generator.allWrittenFiles
      .map((path) => relative(path, from: 'java'))
      .toList();
  generatedPaths.sort();
  File gitignoreFile = new File(join(appDirPath, '..', 'java', '.gitignore'));
  gitignoreFile.writeAsStringSync('''
# This is a generated file.

${generatedPaths.join('\n')}
''');

  // Generate a version file.
  Version version = ApiParseUtil.parseVersionSemVer(nodes);
  File file = new File(join('java', 'version.properties'));
  file.writeAsStringSync('version=${version.major}.${version.minor}\n');

  print('Wrote Java to $srcDirPath.');
}

_generateAsserts(String appDirPath, List<Node> nodes) async {
  var outDirPath = normalize(join(appDirPath, '..', 'example'));
  var outDir = new Directory(outDirPath);
  if (!outDir.existsSync()) outDir.createSync(recursive: true);
  var outputFile = new File(join(outDirPath, 'vm_service_assert.dart'));
  var generator = new dart.DartGenerator();
  dart.api = new dart.Api();
  dart.api.parse(nodes);
  dart.api.generateAsserts(generator);
  outputFile.writeAsStringSync(generator.toString());
  Process.runSync('dartfmt', ['-w', outDirPath]);

  if (_stampPubspecVersion) {
    // Update the pubspec file.
    Version version = ApiParseUtil.parseVersionSemVer(nodes);
    _stampPubspec(version);

    // Validate that the changelog contains an entry for the current version.
    _checkUpdateChangelog(version);
  }

  print('Wrote Dart to ${outputFile.path}.');
}

// Push the major and minor versions into the pubspec.
void _stampPubspec(Version version) {
  final String pattern = 'version: ';
  File file = new File('pubspec.yaml');
  String text = file.readAsStringSync();
  bool found = false;

  text = text.split('\n').map((line) {
    if (line.startsWith(pattern)) {
      found = true;
      Version v = new Version.parse(line.substring(pattern.length));
      String pre = v.preRelease.isEmpty ? null : v.preRelease.join('-');
      String build = v.build.isEmpty ? null : v.build.join('+');
      v = new Version(version.major, version.minor, v.patch,
          pre: pre, build: build);
      return '${pattern}${v.toString()}';
    } else {
      return line;
    }
  }).join('\n');

  if (!found) throw '`${pattern}` not found';

  file.writeAsStringSync(text);
}

void _checkUpdateChangelog(Version version) {
  // Look for `## major.minor`.
  String check = '## ${version.major}.${version.minor}';

  File file = new File('CHANGELOG.md');
  String text = file.readAsStringSync();
  bool containsReleaseNotes =
      text.split('\n').any((line) => line.startsWith(check));
  if (!containsReleaseNotes) {
    throw '`${check}` not found in the CHANGELOG.md file';
  }
}
