// 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 path;
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 {
    return legalTemplateIds.map(retrieveTemplateGenerator);
  }

  static stagehand.Generator retrieveTemplateGenerator(String templateId) {
    return 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,
    );
    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(path.absolute(dir))} using template $templateId...');
    log.stdout('');

    var generator = retrieveTemplateGenerator(templateId);
    await generator.generate(
      path.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 ${path.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 = 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 filePath, List<int> contents) async {
    io.File file = io.File(path.join(dir.path, filePath));

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

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