// Copyright 2016 The Vanadium 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:math';
import 'dart:io';

import '../mobile/device.dart';
import '../mobile/device_spec.dart';
import '../globals.dart';
import '../util.dart';

const String lockProp = 'mHoldingWakeLockSuspendBlocker';

/// Check if the device is locked
Future<bool> _deviceIsLocked(Device device) async {
  Process process = await Process.start(
    'adb',
    ['-s', '${device.id}', 'shell', 'dumpsys', 'power']
  );
  bool isLocked;
  RegExp lockStatusPattern = new RegExp(lockProp + r'=(.*)');
  Stream lineStream = process.stdout
                        .transform(new Utf8Decoder())
                        .transform(new LineSplitter());
  await for (var line in lineStream) {
    Match lockMatcher = lockStatusPattern.firstMatch(line.toString());
    if (lockMatcher != null) {
      isLocked = lockMatcher.group(1) == 'false';
      break;
    }
  }

  process.stderr.drain();
  await process.exitCode;

  return isLocked;
}

/// Unlock devices if the device is locked
Future<int> unlockDevice(Device device) async {

  bool isLocked = await _deviceIsLocked(device);

  if (isLocked == null) {
    printError('adb error: cannot find device $lockProp property');
    return 1;
  }

  if (!isLocked) return 0;

  Process wakeUpAndUnlockProcess = await Process.start(
    'adb',
    ['-s', '${device.id}', 'shell', 'input', 'keyevent', 'KEYCODE_MENU']
  );
  wakeUpAndUnlockProcess.stdout.drain();
  wakeUpAndUnlockProcess.stderr.drain();

  return await wakeUpAndUnlockProcess.exitCode;
}

/// Uninstall tested apps
Future<int> uninstallTestedApps(Map<DeviceSpec, Device> deviceMapping) async {
  int result = 0;

  for (DeviceSpec spec in deviceMapping.keys) {
    Device device = deviceMapping[spec];

    String androidManifestPath
      = normalizePath(spec.appRootPath, 'android/AndroidManifest.xml');
    String androidManifest = await new File(androidManifestPath).readAsString();

    RegExp packagePattern
      = new RegExp(r'<manifest[\s\S]*?package="(\S+)"\s+[\s\S]*?>', multiLine: true);
    Match packageMatcher = packagePattern.firstMatch(androidManifest);
    if (packageMatcher == null) {
      printError('Package name not found in $androidManifestPath');
      return 1;
    }
    String packageName = packageMatcher.group(1);

    Process uninstallProcess = await Process.start(
      'adb',
      ['-s', '${device.id}', 'uninstall', '$packageName']
    );

    Stream lineStream = uninstallProcess.stdout
                         .transform(new Utf8Decoder())
                         .transform(new LineSplitter());
    await for (var line in lineStream) {
      print('Uninstall $packageName on device ${device.id}: ${line.toString().trim()}');
    }

    uninstallProcess.stderr.drain();
    result += await uninstallProcess.exitCode;
  }

  if (result != 0) {
    printError('Cannot uninstall testing apps from devices');
    return 1;
  }
  return 0;
}

/// Get device property
Future<String> getProperty(String deviceID, String propName) async {
  ProcessResult results = await Process.run(
    'adb',
    ['-s', deviceID, 'shell', 'getprop', propName]
  );
  return results.stdout.toString().trim();
}

/// Get device pixels and dpi to compute screen diagonal size in inches
Future<String> getScreenSize(String deviceID) async {
  Process sizeProcess = await Process.start(
    'adb',
    ['-s', '$deviceID', 'shell', 'wm', 'size']
  );
  RegExp sizePattern = new RegExp(r'Physical size:\s*(\d+)x(\d+)');
  Stream sizeLineStream = sizeProcess.stdout
                                     .transform(new Utf8Decoder())
                                    .transform(new LineSplitter());
  int xSize;
  int ySize;
  await for (var line in sizeLineStream) {
    Match sizeMatcher = sizePattern.firstMatch(line.toString());
    if (sizeMatcher != null) {
      xSize = int.parse(sizeMatcher.group(1));
      ySize = int.parse(sizeMatcher.group(2));
      break;
    }
  }

  if (xSize == null || ySize == null) {
    printError('Screen size not found.');
    return null;
  }

  sizeProcess.stderr.drain();

  Process densityProcess = await Process.start(
    'adb',
    ['-s', '$deviceID', 'shell', 'wm', 'density']
  );
  RegExp densityPattern = new RegExp(r'Physical density:\s*(\d+)');
  Stream densityLineStream = densityProcess.stdout
                                           .transform(new Utf8Decoder())
                                           .transform(new LineSplitter());
  int density;
  await for (var line in densityLineStream) {
    Match densityMatcher = densityPattern.firstMatch(line.toString());
    if (densityMatcher != null) {
      density = int.parse(densityMatcher.group(1));
      break;
    }
  }

  if (density == null) {
    printError('Density not found.');
    return null;
  }

  densityProcess.stderr.drain();

  double xInch = xSize / density;
  double yInch = ySize / density;
  double diagonalSize = sqrt(xInch * xInch + yInch * yInch);

  if (diagonalSize < 3.5) return 'small';
  if (diagonalSize < 5) return 'normal';
  if (diagonalSize < 8) return 'large';
  return 'xlarge';
}
