// 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:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/linux/linux_doctor.dart';
import 'package:process/process.dart';

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

// A command that will return typical-looking 'clang++ --version' output with
// the given version number.
FakeCommand _clangPresentCommand(String version) {
  return FakeCommand(
    command: const <String>['clang++', '--version'],
    stdout: '''
clang version $version-6+build1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
''',
  );
}

// A command that will return typical-looking 'cmake --version' output with the
// given version number.
FakeCommand _cmakePresentCommand(String version) {
  return FakeCommand(
    command: const <String>['cmake', '--version'],
    stdout: '''
cmake version $version

CMake suite maintained and supported by Kitware (kitware.com/cmake).
''',
  );
}

// A command that will return typical-looking 'ninja --version' output with the
// given version number.
FakeCommand _ninjaPresentCommand(String version) {
  return FakeCommand(
    command: const <String>['ninja', '--version'],
    stdout: version,
  );
}

// A command that will return typical-looking 'pgk-config --version' output with
// the given version number.
FakeCommand _pkgConfigPresentCommand(String version) {
  return FakeCommand(
    command: const <String>['pkg-config', '--version'],
    stdout: version,
  );
}

/// A command that returns either success or failure for a pkg-config query
/// for [library], depending on [exists].
FakeCommand _libraryCheckCommand(String library, {bool exists = true}) {
  return FakeCommand(
    command: <String>['pkg-config', '--exists', library],
    exitCode: exists ? 0 : 1,
  );
}

// Commands that give positive replies for all the GTK library pkg-config queries.
List<FakeCommand> _gtkLibrariesPresentCommands() {
  return <FakeCommand>[
    _libraryCheckCommand('gtk+-3.0'),
    _libraryCheckCommand('glib-2.0'),
    _libraryCheckCommand('gio-2.0'),
  ];
}

// Commands that give some failures for the GTK library pkg-config queries.
List<FakeCommand> _gtkLibrariesMissingCommands() {
  return <FakeCommand>[
    _libraryCheckCommand('gtk+-3.0'),
    _libraryCheckCommand('glib-2.0', exists: false),
    // No more entries, since the first missing GTK library stops the
    // checks.
  ];
}

// A command that will failure when running '[binary] --version'.
FakeCommand _missingBinaryCommand(String binary) {
  return FakeCommand(
    command: <String>[binary, '--version'],
    exitCode: 1,
  );
}

void main() {
  testWithoutContext('Full validation when everything is available at the necessary version',() async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.installed);
    expect(result.messages, const <ValidationMessage>[
      ValidationMessage('clang version 4.0.1-6+build1'),
      ValidationMessage('cmake version 3.16.3'),
      ValidationMessage('ninja version 1.10.0'),
      ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Partial validation when clang++ version is too old', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('2.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.partial);
    expect(result.messages, const <ValidationMessage>[
      ValidationMessage('clang version 2.0.1-6+build1'),
      ValidationMessage.error('clang++ 3.4.0 or later is required.'),
      ValidationMessage('cmake version 3.16.3'),
      ValidationMessage('ninja version 1.10.0'),
      ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Partial validation when CMake version is too old', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.2.0'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.partial);
    expect(result.messages, const <ValidationMessage>[
      ValidationMessage('clang version 4.0.1-6+build1'),
      ValidationMessage('cmake version 3.2.0'),
      ValidationMessage.error('cmake 3.10.0 or later is required.'),
      ValidationMessage('ninja version 1.10.0'),
      ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Partial validation when ninja version is too old', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('0.8.1'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.partial);
    expect(result.messages, const <ValidationMessage>[
      ValidationMessage('clang version 4.0.1-6+build1'),
      ValidationMessage('cmake version 3.16.3'),
      ValidationMessage('ninja version 0.8.1'),
      ValidationMessage.error('ninja 1.8.0 or later is required.'),
      ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Partial validation when pkg-config version is too old', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.27.0'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.partial);
    expect(result.messages, const <ValidationMessage>[
      ValidationMessage('clang version 4.0.1-6+build1'),
      ValidationMessage('cmake version 3.16.3'),
      ValidationMessage('ninja version 1.10.0'),
      ValidationMessage('pkg-config version 0.27.0'),
      ValidationMessage.error('pkg-config 0.29.0 or later is required.'),
    ]);
  });

  testWithoutContext('Missing validation when CMake is not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _missingBinaryCommand('cmake'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      const ValidationMessage('clang version 4.0.1-6+build1'),
      ValidationMessage.error(userMessages.cmakeMissing),
      const ValidationMessage('ninja version 1.10.0'),
      const ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Missing validation when clang++ is not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _missingBinaryCommand('clang++'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      ValidationMessage.error(userMessages.clangMissing),
      const ValidationMessage('cmake version 3.16.3'),
      const ValidationMessage('ninja version 1.10.0'),
      const ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Missing validation when ninja is not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _missingBinaryCommand('ninja'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      const ValidationMessage('clang version 4.0.1-6+build1'),
      const ValidationMessage('cmake version 3.16.3'),
      ValidationMessage.error(userMessages.ninjaMissing),
      const ValidationMessage('pkg-config version 0.29'),
    ]);
  });

  testWithoutContext('Missing validation when pkg-config is not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _missingBinaryCommand('pkg-config'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      const ValidationMessage('clang version 4.0.1-6+build1'),
      const ValidationMessage('cmake version 3.16.3'),
      const ValidationMessage('ninja version 1.10.0'),
      ValidationMessage.error(userMessages.pkgConfigMissing),
    ]);
  });

  testWithoutContext('Missing validation when GTK libraries are not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesMissingCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      const ValidationMessage('clang version 4.0.1-6+build1'),
      const ValidationMessage('cmake version 3.16.3'),
      const ValidationMessage('ninja version 1.10.0'),
      const ValidationMessage('pkg-config version 0.29'),
      ValidationMessage.error(userMessages.gtkLibrariesMissing),
    ]);
  });

  testWithoutContext('Missing validation when libraries are not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _clangPresentCommand('4.0.1'),
      _cmakePresentCommand('3.16.3'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid', exists: false),
    ]);
    final UserMessages userMessages = UserMessages();
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: userMessages,
    );
    final ValidationResult result = await linuxDoctorValidator.validate();

    expect(result.type, ValidationType.missing);
    expect(result.messages, <ValidationMessage>[
      const ValidationMessage('clang version 4.0.1-6+build1'),
      const ValidationMessage('cmake version 3.16.3'),
      const ValidationMessage('ninja version 1.10.0'),
      const ValidationMessage('pkg-config version 0.29'),
      ValidationMessage.error(userMessages.blkidLibraryMissing),
    ]);
  });

  testWithoutContext('Missing validation when multiple dependencies are not available', () async {
    final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
      _missingBinaryCommand('clang++'),
      _missingBinaryCommand('cmake'),
      _ninjaPresentCommand('1.10.0'),
      _pkgConfigPresentCommand('0.29'),
      ..._gtkLibrariesPresentCommands(),
      _libraryCheckCommand('blkid'),
    ]);
    final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
      processManager: processManager,
      userMessages: UserMessages(),
    );

    final ValidationResult result = await linuxDoctorValidator.validate();
    expect(result.type, ValidationType.missing);
  });
}
