// Copyright (c) 2017 The Chromium 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 dart_io;

import 'package:file/file.dart';
import 'package:file/local.dart' as io;
import 'package:path/path.dart' as path;

import 'utils.dart';

const String _kProvisioningConfigFileEnvironmentVariable = 'FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG';
const String _kTestXcconfigFileName = 'TestConfig.xcconfig';
const FileSystem _fs = io.LocalFileSystem();

/// Patches the given Xcode project adding provisioning certificates and team
/// information required to build and run the project, if
/// FLUTTER_DEVICELAB_XCODE_PROVISIONING_CONFIG is set. If it is not set,
/// we rely on automatic signing by Xcode.
Future<void> prepareProvisioningCertificates(String flutterProjectPath) async {
  final String certificateConfig = await _readProvisioningConfigFile();
  if (certificateConfig == null) {
    // No cert config available, rely on automatic signing by Xcode.
    return;
  }

  await _patchXcconfigFilesIfNotPatched(flutterProjectPath);
  final File testXcconfig = _fs.file(path.join(flutterProjectPath, 'ios/Flutter/$_kTestXcconfigFileName'));
  await testXcconfig.writeAsString(certificateConfig);
}

Future<void> runPodInstallForCustomPodfile(String flutterProjectPath) async {
  final String iosPath = path.join(flutterProjectPath, 'ios');
  exec('pod', <String>['install', '--project-directory=$iosPath']);
}

Future<void> _patchXcconfigFilesIfNotPatched(String flutterProjectPath) async {
  final List<File> xcconfigFiles = <File>[
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Flutter.xcconfig')),
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Debug.xcconfig')),
    _fs.file(path.join(flutterProjectPath, 'ios/Flutter/Release.xcconfig')),
  ];

  bool xcconfigFileExists = false;

  for (final File file in xcconfigFiles) {
    if (await file.exists()) {
      xcconfigFileExists = true;
      const String include = '#include "$_kTestXcconfigFileName"';
      final String contents = await file.readAsString();
      final bool alreadyPatched = contents.contains(include);
      if (!alreadyPatched) {
        final IOSink patchOut = file.openWrite(mode: FileMode.append);
        patchOut.writeln(); // in case EOF is not preceded by line break
        patchOut.writeln(include);
        await patchOut.close();
      }
    }
  }

  if (!xcconfigFileExists) {
    final String candidatesFormatted = xcconfigFiles.map<String>((File f) => f.path).join(', ');
    throw 'Failed to locate a xcconfig file to patch with provisioning profile '
        'info. Tried: $candidatesFormatted';
  }
}

Future<String> _readProvisioningConfigFile() async {
  void throwUsageError(String specificMessage) {
    throw '''
================================================================================
You are attempting to build an XCode project, which requires a provisioning
certificate and team information. The test framework attempted to locate an
.xcconfig file whose path is defined by the environment variable
$_kProvisioningConfigFileEnvironmentVariable.

$specificMessage
================================================================================
'''.trim();
  }

  if (!dart_io.Platform.environment.containsKey(_kProvisioningConfigFileEnvironmentVariable)) {
    print('''
$_kProvisioningConfigFileEnvironmentVariable variable is not defined in your
environment. Relying on automatic signing by Xcode...
'''.trim());
    return null;
  }

  final String filePath = dart_io.Platform.environment[_kProvisioningConfigFileEnvironmentVariable];
  final File file = _fs.file(filePath);
  if (!(await file.exists())) {
    throwUsageError('''
File not found: $filePath

It is defined by environment variable $_kProvisioningConfigFileEnvironmentVariable
'''.trim());
  }

  return file.readAsString();
}

void _checkExitCode(int code) {
  if (code != 0) {
    throw Exception(
      'Unexpected exit code = $code!',
    );
  }
}

Future<void> _execAndCheck(String executable, List<String> args) async {
  _checkExitCode(await exec(executable, args));
}

// Measure the CPU/GPU percentage for [duration] while a Flutter app is running
// on an iOS device (e.g., right after a Flutter driver test has finished, which
// doesn't close the Flutter app, and the Flutter app has an indefinite
// animation). The return should have a format like the following json
// ```
// {"gpu_percentage":12.6,"cpu_percentage":18.15}
// ```
Future<Map<String, dynamic>> measureIosCpuGpu({
    Duration duration = const Duration(seconds: 10),
    String deviceId,
}) async {
  await _execAndCheck('pub', <String>[
    'global',
    'activate',
    'gauge',
    '0.1.4',
  ]);

  await _execAndCheck('pub', <String>[
    'global',
    'run',
    'gauge',
    'ioscpugpu',
    'new',
    if (deviceId != null) ...<String>['-w', deviceId],
    '-l',
    '${duration.inMilliseconds}',
  ]);
  return json.decode(file('$cwd/result.json').readAsStringSync());
}

Future<String> dylibSymbols(String pathToDylib) {
  return eval('nm', <String>['-g', pathToDylib]);
}
