// Copyright 2013 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:async';
import 'dart:convert';
import 'dart:io' as io;

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
import 'package:flutter_plugin_tools/src/common/process_runner.dart';
import 'package:meta/meta.dart';
import 'package:quiver/collection.dart';

/// Creates a packages directory in the given location.
///
/// If [parentDir] is set the packages directory will be created there,
/// otherwise [fileSystem] must be provided and it will be created an arbitrary
/// location in that filesystem.
Directory createPackagesDirectory(
    {Directory? parentDir, FileSystem? fileSystem}) {
  assert(parentDir != null || fileSystem != null,
      'One of parentDir or fileSystem must be provided');
  assert(fileSystem == null || fileSystem is MemoryFileSystem,
      'If using a real filesystem, parentDir must be provided');
  final Directory packagesDir =
      (parentDir ?? fileSystem!.currentDirectory).childDirectory('packages');
  packagesDir.createSync();
  return packagesDir;
}

/// Creates a plugin package with the given [name] in [packagesDirectory].
Directory createFakePlugin(
  String name,
  Directory packagesDirectory, {
  bool withSingleExample = false,
  List<String> withExamples = const <String>[],
  List<List<String>> withExtraFiles = const <List<String>>[],
  bool isFlutter = true,
  // TODO(stuartmorgan): Change these platform switches to support type enums.
  bool isAndroidPlugin = false,
  bool isIosPlugin = false,
  bool isWebPlugin = false,
  bool isLinuxPlugin = false,
  bool isMacOsPlugin = false,
  bool isWindowsPlugin = false,
  bool includeChangeLog = false,
  bool includeVersion = false,
  String version = '0.0.1',
  String parentDirectoryName = '',
}) {
  assert(!(withSingleExample && withExamples.isNotEmpty),
      'cannot pass withSingleExample and withExamples simultaneously');

  Directory parentDirectory = packagesDirectory;
  if (parentDirectoryName != '') {
    parentDirectory = parentDirectory.childDirectory(parentDirectoryName);
  }
  final Directory pluginDirectory = parentDirectory.childDirectory(name);
  pluginDirectory.createSync(recursive: true);

  createFakePubspec(pluginDirectory,
      name: name,
      isFlutter: isFlutter,
      androidSupport: isAndroidPlugin ? PlatformSupport.inline : null,
      iosSupport: isIosPlugin ? PlatformSupport.inline : null,
      webSupport: isWebPlugin ? PlatformSupport.inline : null,
      linuxSupport: isLinuxPlugin ? PlatformSupport.inline : null,
      macosSupport: isMacOsPlugin ? PlatformSupport.inline : null,
      windowsSupport: isWindowsPlugin ? PlatformSupport.inline : null,
      version: includeVersion ? version : null);
  if (includeChangeLog) {
    createFakeCHANGELOG(pluginDirectory, '''
## 0.0.1
  * Some changes.
  ''');
  }

  if (withSingleExample) {
    final Directory exampleDir = pluginDirectory.childDirectory('example')
      ..createSync();
    createFakePubspec(exampleDir,
        name: '${name}_example', isFlutter: isFlutter, publishTo: 'none');
  } else if (withExamples.isNotEmpty) {
    final Directory exampleDir = pluginDirectory.childDirectory('example')
      ..createSync();
    for (final String example in withExamples) {
      final Directory currentExample = exampleDir.childDirectory(example)
        ..createSync();
      createFakePubspec(currentExample,
          name: example, isFlutter: isFlutter, publishTo: 'none');
    }
  }

  final FileSystem fileSystem = pluginDirectory.fileSystem;
  for (final List<String> file in withExtraFiles) {
    final List<String> newFilePath = <String>[pluginDirectory.path, ...file];
    final File newFile = fileSystem.file(fileSystem.path.joinAll(newFilePath));
    newFile.createSync(recursive: true);
  }

  return pluginDirectory;
}

void createFakeCHANGELOG(Directory parent, String texts) {
  parent.childFile('CHANGELOG.md').createSync();
  parent.childFile('CHANGELOG.md').writeAsStringSync(texts);
}

/// Creates a `pubspec.yaml` file with a flutter dependency.
void createFakePubspec(
  Directory parent, {
  String name = 'fake_package',
  bool isFlutter = true,
  PlatformSupport? androidSupport,
  PlatformSupport? iosSupport,
  PlatformSupport? linuxSupport,
  PlatformSupport? macosSupport,
  PlatformSupport? webSupport,
  PlatformSupport? windowsSupport,
  String publishTo = 'http://no_pub_server.com',
  String? version,
}) {
  parent.childFile('pubspec.yaml').createSync();
  String yaml = '''
name: $name
flutter:
  plugin:
    platforms:
''';
  if (androidSupport != null) {
    yaml += _pluginPlatformSection('android', androidSupport, name);
  }
  if (iosSupport != null) {
    yaml += _pluginPlatformSection('ios', iosSupport, name);
  }
  if (webSupport != null) {
    yaml += _pluginPlatformSection('web', webSupport, name);
  }
  if (linuxSupport != null) {
    yaml += _pluginPlatformSection('linux', linuxSupport, name);
  }
  if (macosSupport != null) {
    yaml += _pluginPlatformSection('macos', macosSupport, name);
  }
  if (windowsSupport != null) {
    yaml += _pluginPlatformSection('windows', windowsSupport, name);
  }
  if (isFlutter) {
    yaml += '''
dependencies:
  flutter:
    sdk: flutter
''';
  }
  if (version != null) {
    yaml += '''
version: $version
''';
  }
  if (publishTo.isNotEmpty) {
    yaml += '''
publish_to: $publishTo # Hardcoded safeguard to prevent this from somehow being published by a broken test.
''';
  }
  parent.childFile('pubspec.yaml').writeAsStringSync(yaml);
}

String _pluginPlatformSection(
    String platform, PlatformSupport type, String packageName) {
  if (type == PlatformSupport.federated) {
    return '''
      $platform:
        default_package: ${packageName}_$platform
''';
  }
  switch (platform) {
    case 'android':
      return '''
      android:
        package: io.flutter.plugins.fake
        pluginClass: FakePlugin
''';
    case 'ios':
      return '''
      ios:
        pluginClass: FLTFakePlugin
''';
    case 'linux':
      return '''
      linux:
        pluginClass: FakePlugin
''';
    case 'macos':
      return '''
      macos:
        pluginClass: FakePlugin
''';
    case 'web':
      return '''
      web:
        pluginClass: FakePlugin
        fileName: ${packageName}_web.dart
''';
    case 'windows':
      return '''
      windows:
        pluginClass: FakePlugin
''';
    default:
      assert(false);
      return '';
  }
}

typedef _ErrorHandler = void Function(Error error);

/// Run the command [runner] with the given [args] and return
/// what was printed.
/// A custom [errorHandler] can be used to handle the runner error as desired without throwing.
Future<List<String>> runCapturingPrint(
    CommandRunner<void> runner, List<String> args,
    {_ErrorHandler? errorHandler}) async {
  final List<String> prints = <String>[];
  final ZoneSpecification spec = ZoneSpecification(
    print: (_, __, ___, String message) {
      prints.add(message);
    },
  );
  try {
    await Zone.current
        .fork(specification: spec)
        .run<Future<void>>(() => runner.run(args));
  } on Error catch (e) {
    if (errorHandler == null) {
      rethrow;
    }
    errorHandler(e);
  }

  return prints;
}

/// A mock [ProcessRunner] which records process calls.
class RecordingProcessRunner extends ProcessRunner {
  io.Process? processToReturn;
  final List<ProcessCall> recordedCalls = <ProcessCall>[];

  /// Populate for [io.ProcessResult] to use a String [stdout] instead of a [List] of [int].
  String? resultStdout;

  /// Populate for [io.ProcessResult] to use a String [stderr] instead of a [List] of [int].
  String? resultStderr;

  @override
  Future<int> runAndStream(
    String executable,
    List<String> args, {
    Directory? workingDir,
    bool exitOnError = false,
  }) async {
    recordedCalls.add(ProcessCall(executable, args, workingDir?.path));
    return Future<int>.value(
        processToReturn == null ? 0 : await processToReturn!.exitCode);
  }

  /// Returns [io.ProcessResult] created from [processToReturn], [resultStdout], and [resultStderr].
  @override
  Future<io.ProcessResult> run(
    String executable,
    List<String> args, {
    Directory? workingDir,
    bool exitOnError = false,
    bool logOnError = false,
    Encoding stdoutEncoding = io.systemEncoding,
    Encoding stderrEncoding = io.systemEncoding,
  }) async {
    recordedCalls.add(ProcessCall(executable, args, workingDir?.path));

    final io.Process? process = processToReturn;
    final io.ProcessResult result = process == null
        ? io.ProcessResult(1, 1, '', '')
        : io.ProcessResult(process.pid, await process.exitCode,
            resultStdout ?? process.stdout, resultStderr ?? process.stderr);

    return Future<io.ProcessResult>.value(result);
  }

  @override
  Future<io.Process> start(String executable, List<String> args,
      {Directory? workingDirectory}) async {
    recordedCalls.add(ProcessCall(executable, args, workingDirectory?.path));
    return Future<io.Process>.value(processToReturn);
  }
}

/// A recorded process call.
@immutable
class ProcessCall {
  const ProcessCall(this.executable, this.args, this.workingDir);

  /// The executable that was called.
  final String executable;

  /// The arguments passed to [executable] in the call.
  final List<String> args;

  /// The working directory this process was called from.
  final String? workingDir;

  @override
  bool operator ==(dynamic other) {
    return other is ProcessCall &&
        executable == other.executable &&
        listsEqual(args, other.args) &&
        workingDir == other.workingDir;
  }

  @override
  int get hashCode =>
      (executable.hashCode) ^ (args.hashCode) ^ (workingDir?.hashCode ?? 0);

  @override
  String toString() {
    final List<String> command = <String>[executable, ...args];
    return '"${command.join(' ')}" in $workingDir';
  }
}
