// Copyright 2013 The Flutter Authors
// 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:file/file.dart';
import 'package:flutter_plugin_tools/src/common/process_runner.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/testing.dart';

import 'common/package_command_test.mocks.dart';

// TODO(stuartmorgan): Consider updating call sites to use TestNativePlatform directly; this is a
// shim from the previous implementation, which mocked Platform directly, to fix tests when the
// ability to mock Platform was removed.
NativePlatform createMockPlatform({
  bool isLinux = false,
  bool isMacOS = false,
  bool isWindows = false,
}) {
  assert(
    !(isLinux && isMacOS) && !(isLinux && isWindows) && !(isMacOS && isWindows),
    'Only one platform can be selected.',
  );
  final String platform;
  if (isMacOS) {
    platform = NativePlatform.macOS;
  } else if (isWindows) {
    platform = NativePlatform.windows;
  } else {
    platform = NativePlatform.linux;
  }
  return TestNativePlatform(
    operatingSystem: platform,
    script: isWindows
        ? Uri.file(r'C:\foo\bar', windows: true)
        : Uri.file('/foo/bar', windows: false),
    environment: <String, String>{},
    pathSeparator: isWindows ? r'\' : '/',
  );
}

class MockProcess extends Mock implements io.Process {
  /// Creates a mock process with the given results.
  ///
  /// The default encodings match the ProcessRunner defaults; mocks for
  /// processes run with a different encoding will need to be created with
  /// the matching encoding.
  MockProcess({
    int exitCode = 0,
    String? stdout,
    String? stderr,
    Encoding stdoutEncoding = io.systemEncoding,
    Encoding stderrEncoding = io.systemEncoding,
  }) : _exitCode = exitCode {
    if (stdout != null) {
      _stdoutController.add(stdoutEncoding.encoder.convert(stdout));
    }
    if (stderr != null) {
      _stderrController.add(stderrEncoding.encoder.convert(stderr));
    }
    _stdoutController.close();
    _stderrController.close();
  }

  final int _exitCode;
  final StreamController<List<int>> _stdoutController = StreamController<List<int>>();
  final StreamController<List<int>> _stderrController = StreamController<List<int>>();
  final MockIOSink stdinMock = MockIOSink();

  @override
  int get pid => 99;

  @override
  Future<int> get exitCode async => _exitCode;

  @override
  Stream<List<int>> get stdout => _stdoutController.stream;

  @override
  Stream<List<int>> get stderr => _stderrController.stream;

  @override
  IOSink get stdin => stdinMock;

  @override
  bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) => true;
}

class MockIOSink extends Mock implements IOSink {
  List<String> lines = <String>[];

  @override
  void writeln([Object? obj = '']) => lines.add(obj.toString());
}

/// Creates a mockGitDir that uses [packagesDir]'s parent as its root, and
/// forwards any git commands to [processRunner] to make it easy to mock their
/// output the same way other process calls are mocked.
///
/// The first argument to any `git` command is added to the command to make
/// targeting the mock results easier. For example, `git ls ...` will become
/// a `git-ls ...` call to [processRunner].
///
MockGitDir createForwardingMockGitDir({
  required Directory packagesDir,
  required ProcessRunner processRunner,
}) {
  final gitDir = MockGitDir();
  when(gitDir.path).thenReturn(packagesDir.parent.path);
  when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))).thenAnswer((
    Invocation invocation,
  ) {
    final arguments = List<String>.from(invocation.positionalArguments[0]! as List<String>);
    final String gitCommand = arguments.removeAt(0);
    return processRunner.run('git-$gitCommand', arguments);
  });
  return gitDir;
}
