// Copyright (c) 2020, 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:async';
import 'dart:convert';
import 'dart:io' as io;
import 'dart:math' as math;

import 'package:path/path.dart' as p;
import 'package:stagehand/stagehand.dart' as stagehand;

import '../core.dart';
import '../sdk.dart';

/// A command to create a new project from a set of templates.
class CreateCommand extends DartdevCommand {
  static String defaultTemplateId = 'console-simple';

  static List<String> legalTemplateIds = [
    'console-simple',
    'console-full',
    'package-simple',
    'web-simple'
  ];

  static Iterable<stagehand.Generator> get generators =>
      legalTemplateIds.map(retrieveTemplateGenerator);

  static stagehand.Generator retrieveTemplateGenerator(String templateId) =>
      stagehand.getGenerator(templateId);

  CreateCommand({bool verbose = false})
      : super('create', 'Create a new project.') {
    argParser.addOption(
      'template',
      allowed: legalTemplateIds,
      help: 'The project template to use.',
      defaultsTo: defaultTemplateId,
      abbr: 't',
    );
    argParser.addFlag('pub',
        defaultsTo: true,
        help: "Whether to run 'pub get' after the project has been created.");
    argParser.addFlag(
      'list-templates',
      negatable: false,
      hide: !verbose,
      help: 'List the available templates in JSON format.',
    );
    argParser.addFlag(
      'force',
      negatable: false,
      help: 'Force project generation, even if the target directory already '
          'exists.',
    );
  }

  @override
  String get invocation => '${super.invocation} <directory>';

  @override
  FutureOr<int> run() async {
    if (argResults['list-templates']) {
      log.stdout(_availableTemplatesJson());
      return 0;
    }

    if (argResults.rest.isEmpty) {
      printUsage();
      return 1;
    }

    String templateId = argResults['template'];

    String dir = argResults.rest.first;
    var targetDir = io.Directory(dir);
    if (targetDir.existsSync() && !argResults['force']) {
      log.stderr(
        "Directory '$dir' already exists "
        "(use '--force' to force project generation).",
      );
      return 73;
    }

    log.stdout(
      'Creating ${log.ansi.emphasized(p.absolute(dir))} '
      'using template $templateId...',
    );
    log.stdout('');

    var generator = retrieveTemplateGenerator(templateId);
    await generator.generate(
      p.basename(dir),
      DirectoryGeneratorTarget(generator, io.Directory(dir)),
    );

    if (argResults['pub']) {
      log.stdout('');
      var progress = log.progress('Running pub get');
      var process = await startProcess(
        sdk.pub,
        ['get', '--no-precompile'],
        cwd: dir,
      );

      // Run 'pub get'. We display output from the pub command, but keep the
      // output terse. This is to give the user a sense of the work that pub
      // did without scrolling the previous stdout sections off the screen.
      var buffer = StringBuffer();
      routeToStdout(
        process,
        logToTrace: true,
        listener: (str) {
          // Filter lines like '+ multi_server_socket 1.0.2'.
          if (!str.startsWith('+ ')) {
            buffer.writeln('  $str');
          }
        },
      );
      int code = await process.exitCode;
      if (code != 0) return code;
      progress.finish(showTiming: true);
      log.stdout(buffer.toString().trimRight());
    }

    log.stdout('');
    log.stdout('Created project $dir! In order to get started, type:');
    log.stdout('');
    log.stdout(log.ansi.emphasized('  cd ${p.relative(dir)}'));
    // TODO(devoncarew): Once we have a 'run' command, print out here how to run
    // the app.
    log.stdout('');

    return 0;
  }

  @override
  String get usageFooter {
    int width = legalTemplateIds.map((s) => s.length).reduce(math.max);
    String desc = generators.map((g) {
      String suffix = g.id == defaultTemplateId ? ' (default)' : '';
      return '  ${g.id.padLeft(width)}: ${g.description}$suffix';
    }).join('\n');
    return '\nAvailable templates:\n$desc';
  }

  String _availableTemplatesJson() {
    var items = generators.map((stagehand.Generator generator) {
      var m = {
        'name': generator.id,
        'label': generator.label,
        'description': generator.description,
        'categories': generator.categories
      };

      if (generator.entrypoint != null) {
        m['entrypoint'] = generator.entrypoint.path;
      }

      return m;
    });

    JsonEncoder encoder = const JsonEncoder.withIndent('  ');
    return encoder.convert(items.toList());
  }
}

class DirectoryGeneratorTarget extends stagehand.GeneratorTarget {
  final stagehand.Generator generator;
  final io.Directory dir;

  DirectoryGeneratorTarget(this.generator, this.dir) {
    dir.createSync();
  }

  @override
  Future createFile(String path, List<int> contents) async {
    io.File file = io.File(p.join(dir.path, path));

    String name = p.relative(file.path, from: dir.path);
    log.stdout('  $name');

    await file.create(recursive: true);
    await file.writeAsBytes(contents);
  }
}
