// 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/logger.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/ios/xcresult.dart';
import 'package:flutter_tools/src/macos/xcode.dart';

import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
import 'xcresult_test_data.dart';

void main() {
  // Creates a FakeCommand for the xcresult get call to build the app
  // in the given configuration.
  FakeCommand setUpFakeXCResultGetCommand({
    required String stdout,
    required String tempResultPath,
    required Xcode xcode,
    int exitCode = 0,
    String stderr = '',
  }) {
    return FakeCommand(
      command: <String>[
        ...xcode.xcrunCommand(),
        'xcresulttool',
        'get',
        '--path',
        tempResultPath,
        '--format',
        'json',
      ],
      stdout: stdout,
      stderr: stderr,
      exitCode: exitCode,
      onRun: () {},
    );
  }

  const FakeCommand kWhichSysctlCommand = FakeCommand(
    command: <String>[
      'which',
      'sysctl',
    ],
  );

  const FakeCommand kx64CheckCommand = FakeCommand(
    command: <String>[
      'sysctl',
      'hw.optional.arm64',
    ],
    exitCode: 1,
  );

  XCResultGenerator setupGenerator({
    required String resultJson,
    int exitCode = 0,
    String stderr = '',
  }) {
    final FakeProcessManager fakeProcessManager =
        FakeProcessManager.list(<FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
    ]);
    final Xcode xcode = Xcode.test(
      processManager: fakeProcessManager,
      xcodeProjectInterpreter: XcodeProjectInterpreter.test(
        processManager: fakeProcessManager,
        version: null,
      ),
    );
    fakeProcessManager.addCommands(
      <FakeCommand>[
        setUpFakeXCResultGetCommand(
          stdout: resultJson,
          tempResultPath: _tempResultPath,
          xcode: xcode,
          exitCode: exitCode,
          stderr: stderr,
        ),
      ],
    );
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    return XCResultGenerator(
      resultPath: _tempResultPath,
      xcode: xcode,
      processUtils: processUtils,
    );
  }

  testWithoutContext(
      'correctly parse sample result json when there are issues.', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResult result = await generator.generate();
    expect(result.issues.length, 2);
    expect(result.issues.first.type, XCResultIssueType.error);
    expect(result.issues.first.subType, 'Semantic Issue');
    expect(result.issues.first.message, "Use of undeclared identifier 'asdas'");
    expect(result.issues.first.location, '/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56');
    expect(result.issues.last.type, XCResultIssueType.warning);
    expect(result.issues.last.subType, 'Warning');
    expect(result.issues.last.message,
        "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.");
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json when there are issues but invalid url.', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssuesAndInvalidUrl);
    final XCResult result = await generator.generate();
    expect(result.issues.length, 2);
    expect(result.issues.first.type, XCResultIssueType.error);
    expect(result.issues.first.subType, 'Semantic Issue');
    expect(result.issues.first.message, "Use of undeclared identifier 'asdas'");
    expect(result.issues.first.location, isNull);
    expect(result.issues.first.warnings.first, '(XCResult) The `url` exists but it was failed to be parsed. url: 3:00');
    expect(result.issues.last.type, XCResultIssueType.warning);
    expect(result.issues.last.subType, 'Warning');
    expect(result.issues.last.message,
        "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.");
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json and discard all warnings', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResultIssueDiscarder discarder = XCResultIssueDiscarder(typeMatcher: XCResultIssueType.warning);
    final XCResult result = await generator.generate(issueDiscarders: <XCResultIssueDiscarder>[discarder]);
    expect(result.issues.length, 1);
    expect(result.issues.first.type, XCResultIssueType.error);
    expect(result.issues.first.subType, 'Semantic Issue');
    expect(result.issues.first.message, "Use of undeclared identifier 'asdas'");
    expect(result.issues.first.location, '/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56');
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json and discard base on subType', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResultIssueDiscarder discarder = XCResultIssueDiscarder(subTypeMatcher: RegExp(r'^Warning$'));
    final XCResult result = await generator.generate(issueDiscarders: <XCResultIssueDiscarder>[discarder]);
    expect(result.issues.length, 1);
    expect(result.issues.first.type, XCResultIssueType.error);
    expect(result.issues.first.subType, 'Semantic Issue');
    expect(result.issues.first.message, "Use of undeclared identifier 'asdas'");
    expect(result.issues.first.location, '/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56');
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json and discard base on message', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResultIssueDiscarder discarder = XCResultIssueDiscarder(messageMatcher: RegExp(r"^The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.$"));
    final XCResult result = await generator.generate(issueDiscarders: <XCResultIssueDiscarder>[discarder]);
    expect(result.issues.length, 1);
    expect(result.issues.first.type, XCResultIssueType.error);
    expect(result.issues.first.subType, 'Semantic Issue');
    expect(result.issues.first.message, "Use of undeclared identifier 'asdas'");
    expect(result.issues.first.location, '/Users/m/Projects/test_create/ios/Runner/AppDelegate.m:7:56');
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json and discard base on location', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResultIssueDiscarder discarder = XCResultIssueDiscarder(locationMatcher: RegExp(r'/Users/m/Projects/test_create/ios/Runner/AppDelegate.m'));
    final XCResult result = await generator.generate(issueDiscarders: <XCResultIssueDiscarder>[discarder]);
    expect(result.issues.length, 1);
    expect(result.issues.first.type, XCResultIssueType.warning);
    expect(result.issues.first.subType, 'Warning');
    expect(result.issues.first.message,
        "The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.");
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'correctly parse sample result json with multiple discarders.', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonWithIssues);
    final XCResultIssueDiscarder discardWarnings = XCResultIssueDiscarder(typeMatcher: XCResultIssueType.warning);
    final XCResultIssueDiscarder discardSemanticIssues = XCResultIssueDiscarder(subTypeMatcher: RegExp(r'^Semantic Issue$'));
    final XCResult result = await generator.generate(issueDiscarders: <XCResultIssueDiscarder>[discardWarnings, discardSemanticIssues]);
    expect(result.issues, isEmpty);
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext('correctly parse sample result json when no issues.',
      () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonNoIssues);
    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, isTrue);
    expect(result.parsingErrorMessage, isNull);
  });

  testWithoutContext(
      'error: `xcresulttool get` process fail should return an `XCResult` with stderr as `parsingErrorMessage`.',
      () async {
    const String fakeStderr = 'Fake: fail to parse result json.';
    final XCResultGenerator generator = setupGenerator(
      resultJson: '',
      exitCode: 1,
      stderr: fakeStderr,
    );

    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, false);
    expect(result.parsingErrorMessage, fakeStderr);
  });

  testWithoutContext('error: `xcresulttool get` no stdout', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: '');

    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, false);
    expect(result.parsingErrorMessage,
        'xcresult parser: Unrecognized top level json format.');
  });

  testWithoutContext('error: wrong top level json format.', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: '[]');

    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, false);
    expect(result.parsingErrorMessage,
        'xcresult parser: Unrecognized top level json format.');
  });

  testWithoutContext('error: fail to parse issue map', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: '{}');

    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, false);
    expect(result.parsingErrorMessage,
        'xcresult parser: Failed to parse the issues map.');
  });

  testWithoutContext('error: invalid issue map', () async {
    final XCResultGenerator generator = setupGenerator(resultJson: kSampleResultJsonInvalidIssuesMap);

    final XCResult result = await generator.generate();
    expect(result.issues.length, 0);
    expect(result.parseSuccess, false);
    expect(result.parsingErrorMessage,
        'xcresult parser: Failed to parse the issues map.');
  });
}

const String _tempResultPath = 'temp';
