// 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 'package:process/process.dart';

import '../base/file_system.dart';
import '../base/logger.dart';
import '../project.dart';
import '../project_validator.dart';
import '../project_validator_result.dart';
import '../runner/flutter_command.dart';

class ValidateProject {
  ValidateProject({
    required this.fileSystem,
    required this.logger,
    required this.allProjectValidators,
    required this.userPath,
    required this.processManager,
    this.verbose = false,
    this.machine = false,
  });

  final FileSystem fileSystem;
  final Logger logger;
  final bool verbose;
  final bool machine;
  final String userPath;
  final List<ProjectValidator> allProjectValidators;
  final ProcessManager processManager;

  Future<FlutterCommandResult> run() async {
    final Directory workingDirectory = userPath.isEmpty ? fileSystem.currentDirectory : fileSystem.directory(userPath);

    final FlutterProject project =  FlutterProject.fromDirectory(workingDirectory);
    final Map<ProjectValidator, Future<List<ProjectValidatorResult>>> results = <ProjectValidator, Future<List<ProjectValidatorResult>>>{};

    bool hasCrash = false;
    for (final ProjectValidator validator in allProjectValidators) {
      if (validator.machineOutput != machine) {
        continue;
      }
      if (!results.containsKey(validator) && validator.supportsProject(project)) {
        results[validator] = validator
            .start(project)
            .then(
              (List<ProjectValidatorResult> results) => results,
              onError: (Object exception, StackTrace trace) {
                hasCrash = true;
                return <ProjectValidatorResult>[
                  ProjectValidatorResult.crash(exception, trace),
                ];
              },
            );
      }
    }

    final StringBuffer buffer = StringBuffer();
    if (machine) {
      // Print properties
      buffer.write('{\n');
      for (final Future<List<ProjectValidatorResult>> resultListFuture in results.values) {
        final List<ProjectValidatorResult> resultList = await resultListFuture;
        int count = 0;
        for (final ProjectValidatorResult result in resultList) {
          count++;
          buffer.write('  "${result.name}": ${result.value}${count < resultList.length ? ',' : ''}\n');
        }
      }
      buffer.write('}');
      logger.printStatus(buffer.toString());
    } else {
      final List<String> resultsString = <String>[];
      for (final ProjectValidator validator in results.keys) {
        if (results[validator] != null) {
          resultsString.add(validator.title);
          addResultString(validator.title, await results[validator], resultsString);
        }
      }
      buffer.writeAll(resultsString, '\n');
      logger.printBox(buffer.toString());
    }

    if (hasCrash) {
      return const FlutterCommandResult(ExitStatus.fail);
    }
    return const FlutterCommandResult(ExitStatus.success);
  }


  void addResultString(final String title, final List<ProjectValidatorResult>? results, final List<String> resultsString) {
    if (results != null) {
      for (final ProjectValidatorResult result in results) {
        resultsString.add(getStringResult(result));
      }
    }
  }

  String getStringResult(ProjectValidatorResult result) {
    final String icon;
    switch(result.status) {
      case StatusProjectValidator.error:
        icon = '[✗]';
      case StatusProjectValidator.info:
      case StatusProjectValidator.success:
        icon = '[✓]';
      case StatusProjectValidator.warning:
        icon = '[!]';
      case StatusProjectValidator.crash:
        icon = '[☠]';
    }

    return '$icon $result';
  }
}
