// 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 'dart:collection';

import 'package:process/process.dart';

import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/platform.dart';
import 'cache.dart';
import 'convert.dart';
import 'dart_pub_json_formatter.dart';
import 'flutter_manifest.dart';
import 'project.dart';
import 'project_validator_result.dart';
import 'version.dart';

abstract class ProjectValidator {
  const ProjectValidator();
  String get title;
  bool get machineOutput => false;
  bool supportsProject(FlutterProject project);
  /// Can return more than one result in case a file/command have a lot of info to share to the user
  Future<List<ProjectValidatorResult>> start(FlutterProject project);
}

abstract class MachineProjectValidator extends ProjectValidator {
  const MachineProjectValidator();

  @override
  bool get machineOutput => true;
}

/// Validator run for all platforms that extract information from the pubspec.yaml.
///
/// Specific info from different platforms should be written in their own ProjectValidator.
class VariableDumpMachineProjectValidator extends MachineProjectValidator {
  VariableDumpMachineProjectValidator({
    required this.logger,
    required this.fileSystem,
    required this.platform,
  });

  final Logger logger;
  final FileSystem fileSystem;
  final Platform platform;

  String _toJsonValue(Object? obj) {
    String value = obj.toString();
    if (obj is String) {
      value = '"$obj"';
    }
    value = value.replaceAll(r'\', r'\\');
    return value;
  }

  @override
  Future<List<ProjectValidatorResult>> start(FlutterProject project) async {
    final List<ProjectValidatorResult> result = <ProjectValidatorResult>[];

    result.add(ProjectValidatorResult(
      name: 'FlutterProject.directory',
      value: _toJsonValue(project.directory.absolute.path),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.metadataFile',
      value: _toJsonValue(project.metadataFile.absolute.path),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.android.exists',
      value: _toJsonValue(project.android.existsSync()),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.ios.exists',
      value: _toJsonValue(project.ios.exists),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.web.exists',
      value: _toJsonValue(project.web.existsSync()),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.macos.exists',
      value: _toJsonValue(project.macos.existsSync()),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.linux.exists',
      value: _toJsonValue(project.linux.existsSync()),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.windows.exists',
      value: _toJsonValue(project.windows.existsSync()),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.fuchsia.exists',
      value: _toJsonValue(project.fuchsia.existsSync()),
      status: StatusProjectValidator.info,
    ));

    result.add(ProjectValidatorResult(
      name: 'FlutterProject.android.isKotlin',
      value: _toJsonValue(project.android.isKotlin),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.ios.isSwift',
      value: _toJsonValue(project.ios.isSwift),
      status: StatusProjectValidator.info,
    ));

    result.add(ProjectValidatorResult(
      name: 'FlutterProject.isModule',
      value: _toJsonValue(project.isModule),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'FlutterProject.isPlugin',
      value: _toJsonValue(project.isPlugin),
      status: StatusProjectValidator.info,
    ));

    result.add(ProjectValidatorResult(
      name: 'FlutterProject.manifest.appname',
      value: _toJsonValue(project.manifest.appName),
      status: StatusProjectValidator.info,
    ));

    // FlutterVersion
    final FlutterVersion version = FlutterVersion(
      flutterRoot: Cache.flutterRoot!,
      fs: fileSystem,
    );
    result.add(ProjectValidatorResult(
      name: 'FlutterVersion.frameworkRevision',
      value: _toJsonValue(version.frameworkRevision),
      status: StatusProjectValidator.info,
    ));

    // Platform
    result.add(ProjectValidatorResult(
      name: 'Platform.operatingSystem',
      value: _toJsonValue(platform.operatingSystem),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.isAndroid',
      value: _toJsonValue(platform.isAndroid),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.isIOS',
      value: _toJsonValue(platform.isIOS),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.isWindows',
      value: _toJsonValue(platform.isWindows),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.isMacOS',
      value: _toJsonValue(platform.isMacOS),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.isFuchsia',
      value: _toJsonValue(platform.isFuchsia),
      status: StatusProjectValidator.info,
    ));
    result.add(ProjectValidatorResult(
      name: 'Platform.pathSeparator',
      value: _toJsonValue(platform.pathSeparator),
      status: StatusProjectValidator.info,
    ));

    // Cache
    result.add(ProjectValidatorResult(
      name: 'Cache.flutterRoot',
      value: _toJsonValue(Cache.flutterRoot),
      status: StatusProjectValidator.info,
    ));
    return result;
  }

  @override
  bool supportsProject(FlutterProject project) {
    // this validator will run for any type of project
    return true;
  }

  @override
  String get title => 'Machine JSON variable dump';
}

/// Validator run for all platforms that extract information from the pubspec.yaml.
///
/// Specific info from different platforms should be written in their own ProjectValidator.
class GeneralInfoProjectValidator extends ProjectValidator {
  @override
  Future<List<ProjectValidatorResult>> start(FlutterProject project) async {
    final FlutterManifest flutterManifest = project.manifest;
    final List<ProjectValidatorResult> result = <ProjectValidatorResult>[];
    final ProjectValidatorResult appNameValidatorResult = _getAppNameResult(flutterManifest);
    result.add(appNameValidatorResult);
    final String supportedPlatforms = _getSupportedPlatforms(project);
    if (supportedPlatforms.isEmpty) {
      return result;
    }
    final ProjectValidatorResult supportedPlatformsResult = ProjectValidatorResult(
        name: 'Supported Platforms',
        value: supportedPlatforms,
        status: StatusProjectValidator.success
    );
    final ProjectValidatorResult isFlutterPackage = _isFlutterPackageValidatorResult(flutterManifest);
    result.addAll(<ProjectValidatorResult>[supportedPlatformsResult, isFlutterPackage]);
    if (flutterManifest.flutterDescriptor.isNotEmpty) {
      result.add(_materialDesignResult(flutterManifest));
      result.add(_pluginValidatorResult(flutterManifest));
    }
    result.add(await project.android.validateJavaAndGradleAgpVersions());
    return result;
  }

  ProjectValidatorResult _getAppNameResult(FlutterManifest flutterManifest) {
    final String appName = flutterManifest.appName;
    const String name = 'App Name';
    if (appName.isEmpty) {
      return const ProjectValidatorResult(
          name: name,
          value: 'name not found',
          status: StatusProjectValidator.error
      );
    }
    return ProjectValidatorResult(
        name: name,
        value: appName,
        status: StatusProjectValidator.success
    );
  }

  ProjectValidatorResult _isFlutterPackageValidatorResult(FlutterManifest flutterManifest) {
    final String value;
    final StatusProjectValidator status;
    if (flutterManifest.flutterDescriptor.isNotEmpty) {
      value = 'yes';
      status = StatusProjectValidator.success;
    } else {
      value = 'no';
      status = StatusProjectValidator.warning;
    }

    return ProjectValidatorResult(
        name: 'Is Flutter Package',
        value: value,
        status: status
    );
  }

  ProjectValidatorResult _materialDesignResult(FlutterManifest flutterManifest) {
    return ProjectValidatorResult(
      name: 'Uses Material Design',
      value: flutterManifest.usesMaterialDesign? 'yes' : 'no',
      status: StatusProjectValidator.success
    );
  }

  String _getSupportedPlatforms(FlutterProject project) {
    return project.getSupportedPlatforms().map((SupportedPlatform platform) => platform.name).join(', ');
  }

  ProjectValidatorResult _pluginValidatorResult(FlutterManifest flutterManifest) {
    return ProjectValidatorResult(
      name: 'Is Plugin',
      value: flutterManifest.isPlugin? 'yes' : 'no',
      status: StatusProjectValidator.success
    );
  }

  @override
  bool supportsProject(FlutterProject project) {
    // this validator will run for any type of project
    return true;
  }

  @override
  String get title => 'General Info';
}

class PubDependenciesProjectValidator extends ProjectValidator {
  const PubDependenciesProjectValidator(this._processManager);
  final ProcessManager _processManager;

  @override
  Future<List<ProjectValidatorResult>> start(FlutterProject project) async {
    const String name = 'Dart dependencies';
    final ProcessResult processResult = await _processManager.run(<String>['dart', 'pub', 'deps', '--json']);
    if (processResult.stdout is! String) {
      return <ProjectValidatorResult>[
        _createProjectValidatorError(name, 'Command dart pub deps --json failed')
      ];
    }

    final LinkedHashMap<String, dynamic> jsonResult;
    final List<ProjectValidatorResult> result = <ProjectValidatorResult>[];
    try {
      jsonResult = json.decode(
        processResult.stdout.toString()
      ) as LinkedHashMap<String, dynamic>;
    } on FormatException {
      result.add(_createProjectValidatorError(name, processResult.stderr.toString()));
      return result;
    }

    final DartPubJson dartPubJson = DartPubJson(jsonResult);
    final List <String> dependencies = <String>[];

    // Information retrieved from the pubspec.lock file if a dependency comes from
    // the hosted url https://pub.dartlang.org we ignore it or if the package
    // is the current directory being analyzed (root).
    final Set<String> hostedDependencies = <String>{'hosted', 'root'};

    for (final DartDependencyPackage package in dartPubJson.packages) {
      if (!hostedDependencies.contains(package.source)) {
        dependencies.addAll(package.dependencies);
      }
    }

    final String value;
    if (dependencies.isNotEmpty) {
      final String verb = dependencies.length == 1 ? 'is' : 'are';
      value = '${dependencies.join(', ')} $verb not hosted';
    } else {
      value = 'All pub dependencies are hosted on https://pub.dartlang.org';
    }

    result.add(
       ProjectValidatorResult(
        name: name,
        value: value,
        status: StatusProjectValidator.info,
      )
    );

    return result;
  }

  @override
  bool supportsProject(FlutterProject project) {
    return true;
  }

  @override
  String get title => 'Pub dependencies';

  ProjectValidatorResult _createProjectValidatorError(String name, String value) {
    return ProjectValidatorResult(name: name, value: value, status: StatusProjectValidator.error);
  }
}
