// 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:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/commands/clean.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:meta/meta.dart';
import 'package:test/fake.dart';

import '../../src/common.dart';
import '../../src/context.dart';

void main() {
  group('clean command', () {
    late Xcode xcode;
    late FakeXcodeProjectInterpreter xcodeProjectInterpreter;

    setUp(() {
      xcodeProjectInterpreter = FakeXcodeProjectInterpreter();
      xcode = Xcode.test(
        processManager: FakeProcessManager.any(),
        xcodeProjectInterpreter: xcodeProjectInterpreter,
      );
    });

    group('general', () {
      late MemoryFileSystem fs;
      late Directory buildDirectory;

      setUp(() {
        fs = MemoryFileSystem.test();

        final Directory currentDirectory = fs.currentDirectory;
        buildDirectory = currentDirectory.childDirectory('build');
        buildDirectory.createSync(recursive: true);
      });

      testUsingContext('$CleanCommand removes build and .dart_tool and ephemeral directories, cleans Xcode for iOS and macOS', () async {
        final FlutterProject projectUnderTest = setupProjectUnderTest(fs.currentDirectory, true);
        // Xcode is installed and version satisfactory.
        xcodeProjectInterpreter.isInstalled = true;
        xcodeProjectInterpreter.version = Version(1000, 0, 0);
        await CleanCommand().runCommand();

        expect(buildDirectory, isNot(exists));
        expect(projectUnderTest.dartTool, isNot(exists));
        expect(projectUnderTest.android.ephemeralDirectory, isNot(exists));

        expect(projectUnderTest.ios.ephemeralDirectory, isNot(exists));
        expect(projectUnderTest.ios.ephemeralModuleDirectory, isNot(exists));
        expect(projectUnderTest.ios.generatedXcodePropertiesFile, isNot(exists));
        expect(projectUnderTest.ios.generatedEnvironmentVariableExportScript, isNot(exists));
        expect(projectUnderTest.ios.deprecatedCompiledDartFramework, isNot(exists));
        expect(projectUnderTest.ios.deprecatedProjectFlutterFramework, isNot(exists));
        expect(projectUnderTest.ios.flutterPodspec, isNot(exists));

        expect(projectUnderTest.linux.ephemeralDirectory, isNot(exists));
        expect(projectUnderTest.macos.ephemeralDirectory, isNot(exists));
        expect(projectUnderTest.windows.ephemeralDirectory, isNot(exists));

        expect(projectUnderTest.flutterPluginsFile, isNot(exists));
        expect(projectUnderTest.flutterPluginsDependenciesFile, isNot(exists));
        expect(projectUnderTest.packagesFile, isNot(exists));

        expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[
          CleanWorkspaceCall('/ios/Runner.xcworkspace', 'Runner', false),
          CleanWorkspaceCall('/macos/Runner.xcworkspace', 'Runner', false),
        ]);
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
        Xcode: () => xcode,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });

      testUsingContext('$CleanCommand does not run when there is no xcworkspace', () async {
        setupProjectUnderTest(fs.currentDirectory, false);
        // Xcode is installed and version satisfactory.
        xcodeProjectInterpreter.isInstalled = true;
        xcodeProjectInterpreter.version = Version(1000, 0, 0);
        await CleanCommand().runCommand();

        expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[]);
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
        Xcode: () => xcode,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });

      testUsingContext('$CleanCommand cleans Xcode verbosely for iOS and macOS', () async {
        setupProjectUnderTest(fs.currentDirectory, true);
        // Xcode is installed and version satisfactory.
        xcodeProjectInterpreter.isInstalled = true;
        xcodeProjectInterpreter.version = Version(1000, 0, 0);

        await CleanCommand(verbose: true).runCommand();

        expect(xcodeProjectInterpreter.workspaces, const <CleanWorkspaceCall>[
          CleanWorkspaceCall('/ios/Runner.xcworkspace', 'Runner', true),
          CleanWorkspaceCall('/macos/Runner.xcworkspace', 'Runner', true),
        ]);
      }, overrides: <Type, Generator>{
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
        Xcode: () => xcode,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });
    });

    group('Windows', () {
      late FakePlatform windowsPlatform;
      late MemoryFileSystem fileSystem;
      late FileExceptionHandler exceptionHandler;

      setUp(() {
        windowsPlatform = FakePlatform(operatingSystem: 'windows');
        exceptionHandler = FileExceptionHandler();
        fileSystem = MemoryFileSystem.test(opHandle: exceptionHandler.opHandle);
      });

      testUsingContext('$CleanCommand prints a helpful error message on Windows', () async {
        xcodeProjectInterpreter.isInstalled = false;

        final File file = fileSystem.file('file')..createSync();
        exceptionHandler.addError(
          file,
          FileSystemOp.delete,
          const FileSystemException('Deletion failed'),
        );

        final CleanCommand command = CleanCommand();
        command.deleteFile(file);
        expect(testLogger.errorText, contains('A program may still be using a file'));
      }, overrides: <Type, Generator>{
        Platform: () => windowsPlatform,
        Xcode: () => xcode,
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('$CleanCommand handles missing delete permissions', () async {
        final FileExceptionHandler handler = FileExceptionHandler();
        final FileSystem fileSystem = MemoryFileSystem.test(opHandle: handler.opHandle);
        final File throwingFile = fileSystem.file('bad')
          ..createSync();
        handler.addError(throwingFile, FileSystemOp.delete, const FileSystemException('OS error: Access Denied'));

        xcodeProjectInterpreter.isInstalled = false;

        final CleanCommand command = CleanCommand();
        command.deleteFile(throwingFile);

        expect(testLogger.errorText, contains('Failed to remove bad. A program may still be using a file in the directory or the directory itself'));
        expect(throwingFile, exists);
      }, overrides: <Type, Generator>{
        Platform: () => windowsPlatform,
        Xcode: () => xcode,
      });
    });
  });
}

FlutterProject setupProjectUnderTest(Directory currentDirectory, bool setupXcodeWorkspace) {
  // This needs to be run within testWithoutContext and not setUp since FlutterProject uses context.
  final FlutterProject projectUnderTest = FlutterProject.fromDirectory(currentDirectory);
  if (setupXcodeWorkspace == true) {
    projectUnderTest.ios.hostAppRoot.childDirectory('Runner.xcworkspace').createSync(recursive: true);
    projectUnderTest.macos.hostAppRoot.childDirectory('Runner.xcworkspace').createSync(recursive: true);
  }
  projectUnderTest.dartTool.createSync(recursive: true);
  projectUnderTest.packagesFile.createSync(recursive: true);
  projectUnderTest.android.ephemeralDirectory.createSync(recursive: true);

  projectUnderTest.ios.ephemeralDirectory.createSync(recursive: true);
  projectUnderTest.ios.ephemeralModuleDirectory.createSync(recursive: true);
  projectUnderTest.ios.generatedXcodePropertiesFile.createSync(recursive: true);
  projectUnderTest.ios.generatedEnvironmentVariableExportScript.createSync(recursive: true);
  projectUnderTest.ios.deprecatedCompiledDartFramework.createSync(recursive: true);
  projectUnderTest.ios.deprecatedProjectFlutterFramework.createSync(recursive: true);
  projectUnderTest.ios.flutterPodspec.createSync(recursive: true);

  projectUnderTest.linux.ephemeralDirectory.createSync(recursive: true);
  projectUnderTest.macos.ephemeralDirectory.createSync(recursive: true);
  projectUnderTest.windows.ephemeralDirectory.createSync(recursive: true);
  projectUnderTest.flutterPluginsFile.createSync(recursive: true);
  projectUnderTest.flutterPluginsDependenciesFile.createSync(recursive: true);

  return projectUnderTest;
}

class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterpreter {
  @override
  bool isInstalled = true;

  @override
  Version version = Version(0, 0, 0);

  @override
  Future<XcodeProjectInfo> getInfo(String projectPath, {String? projectFilename}) async {
    return XcodeProjectInfo(
      const <String>[],
      const <String>[],
      <String>['Runner'],
      BufferLogger.test(),
    );
  }

  final List<CleanWorkspaceCall> workspaces = <CleanWorkspaceCall>[];

  @override
  Future<void> cleanWorkspace(String workspacePath, String scheme, {bool verbose = false}) async {
    workspaces.add(CleanWorkspaceCall(workspacePath, scheme, verbose));
    return;
  }
}

@immutable
class CleanWorkspaceCall {
  const CleanWorkspaceCall(this.workspacePath, this.scheme, this.verbose);

  final String workspacePath;
  final String scheme;
  final bool verbose;

  @override
  bool operator ==(Object other) => other is CleanWorkspaceCall &&
    workspacePath == other.workspacePath &&
    scheme == other.scheme &&
    verbose == other.verbose;

  @override
  int get hashCode => Object.hash(workspacePath, scheme, verbose);

  @override
  String toString() => '{$workspacePath, $scheme, $verbose}';
}
