// Copyright 2016 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 'dart:async';

import 'package:test/test.dart';
import 'package:collection/collection.dart';

import 'package:cocoon_agent/src/adb.dart';
import 'package:cocoon_agent/src/utils.dart';

void main() {
  group('AndroidDeviceDiscovery', () {
    FakeAndroidDeviceDiscovery deviceDiscovery;

    setUp(() {
      deviceDiscovery = FakeAndroidDeviceDiscovery();
    });

    test('deviceDiscovery no retries', () async {
      deviceDiscovery.outputs = <dynamic>['List of devices attached'];
      expect(await deviceDiscovery.discoverDevices(), isEmpty);
      StringBuffer sb = new StringBuffer();
      sb.writeln('List of devices attached');
      sb.writeln('ZY223JQNMR      device');
      deviceDiscovery.outputs = <dynamic>[sb.toString()];
      List<Device> devices = await deviceDiscovery.discoverDevices();
      expect(devices.length, equals(1));
      expect(devices[0].deviceId, equals('ZY223JQNMR'));
    });

    test('deviceDiscovery retries', () async {
      StringBuffer sb = new StringBuffer();
      sb.writeln('List of devices attached');
      sb.writeln('ZY223JQNMR      device');
      deviceDiscovery.outputs = <dynamic>[
        new TimeoutException('a'),
        new TimeoutException('b'),
        sb.toString()
      ];
      List<Device> devices =
          await deviceDiscovery.discoverDevices(retriesDelayMs: 1);
      expect(devices.length, equals(1));
      expect(devices[0].deviceId, equals('ZY223JQNMR'));
    });

    test('deviceDiscovery fails', () async {
      deviceDiscovery.outputs = <dynamic>[
        new TimeoutException('a'),
        new TimeoutException('b'),
        new TimeoutException('c')
      ];
      expect(() => deviceDiscovery.discoverDevices(retriesDelayMs: 1),
          throwsA(TypeMatcher<TimeoutException>()));
    });
  });

  group('Android device', () {
    AndroidDevice device;

    setUp(() {
      FakeDevice.resetLog();
      device = null;
      device = FakeDevice();
    });

    tearDown(() {});

    group('isAwake/isAsleep', () {
      test('reads Awake', () async {
        FakeDevice.pretendAwake();
        expect(await device.isAwake(), isTrue);
        expect(await device.isAsleep(), isFalse);
      });

      test('reads Asleep', () async {
        FakeDevice.pretendAsleep();
        expect(await device.isAwake(), isFalse);
        expect(await device.isAsleep(), isTrue);
      });
    });

    group('togglePower', () {
      test('sends power event', () async {
        await device.togglePower();
        expectLog([
          cmd(command: 'input', arguments: ['keyevent', '26']),
        ]);
      });
    });

    group('wakeUp', () {
      test('when awake', () async {
        FakeDevice.pretendAwake();
        await device.wakeUp();
        expectLog([
          cmd(command: 'dumpsys', arguments: ['power']),
        ]);
      });

      test('when asleep', () async {
        FakeDevice.pretendAsleep();
        await device.wakeUp();
        expectLog([
          cmd(command: 'dumpsys', arguments: ['power']),
          cmd(command: 'input', arguments: ['keyevent', '26']),
        ]);
      });
    });

    group('sendToSleep', () {
      test('when asleep', () async {
        FakeDevice.pretendAsleep();
        await device.sendToSleep();
        expectLog([
          cmd(command: 'dumpsys', arguments: ['power']),
        ]);
      });

      test('when awake', () async {
        FakeDevice.pretendAwake();
        await device.sendToSleep();
        expectLog([
          cmd(command: 'dumpsys', arguments: ['power']),
          cmd(command: 'input', arguments: ['keyevent', '26']),
        ]);
      });
    });

    group('unlock', () {
      test('sends unlock event', () async {
        FakeDevice.pretendAwake();
        await device.unlock();
        expectLog([
          cmd(command: 'dumpsys', arguments: ['power']),
          cmd(command: 'input', arguments: ['keyevent', '82']),
        ]);
      });
    });

    group('battery health', () {
      test('battery health unknown', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_UNKNOWN);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isTrue);
        expect(batteryHealth.details, contains('unknown'));
      });

      test('battery health good', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_GOOD);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isTrue);
        expect(batteryHealth.details, isNull);
      });

      test('battery overheated', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_OVERHEAT);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isFalse);
        expect(batteryHealth.details, contains('overheat'));
      });

      test('battery dead', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_DEAD);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isFalse);
        expect(batteryHealth.details, contains('dead'));
      });

      test('battery over voltage', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_OVER_VOLTAGE);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isFalse);
        expect(batteryHealth.details, contains('over voltage'));
      });

      test('battery health unspecified failure', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_UNSPECIFIED_FAILURE);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isFalse);
        expect(batteryHealth.details, contains('Unspecified'));
      });

      test('battery cold', () async {
        FakeDevice.pretendBatteryHealth(
            AndroidBatteryHealth.BATTERY_HEALTH_COLD);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isFalse);
        expect(batteryHealth.details, contains('cold'));
      });

      test('battery health value not recognized', () async {
        FakeDevice.pretendBatteryHealth(42);
        final HealthCheckResult batteryHealth = await device.batteryHealth();
        expect(batteryHealth.succeeded, isTrue);
        expect(batteryHealth.details, contains('42'));
      });
    });
  });
}

void expectLog(List<CommandArgs> log) {
  expect(FakeDevice.commandLog, log);
}

CommandArgs cmd(
        {String command, List<String> arguments, Map<String, String> env}) =>
    CommandArgs(command: command, arguments: arguments, env: env);

typedef dynamic ExitErrorFactory();

class CommandArgs {
  CommandArgs({this.command, this.arguments, this.env});

  final String command;
  final List<String> arguments;
  final Map<String, String> env;

  @override
  String toString() =>
      'CommandArgs(command: $command, arguments: $arguments, env: $env)';

  @override
  bool operator ==(Object other) {
    if (other is CommandArgs) {
      return other.command == this.command &&
          const ListEquality<String>()
              .equals(other.arguments, this.arguments) &&
          const MapEquality<String, String>().equals(other.env, this.env);
    }
    return false;
  }

  @override
  int get hashCode => 17 * (17 * command.hashCode + _hashArguments) + _hashEnv;

  int get _hashArguments => arguments != null
      ? const ListEquality<String>().hash(arguments)
      : null.hashCode;

  int get _hashEnv => env != null
      ? const MapEquality<String, String>().hash(env)
      : null.hashCode;
}

class FakeDevice extends AndroidDevice {
  FakeDevice({String deviceId}) : super(deviceId: deviceId);

  static String output = '';
  static ExitErrorFactory exitErrorFactory = () => null;

  static List<CommandArgs> commandLog = <CommandArgs>[];

  static void resetLog() {
    commandLog.clear();
  }

  static void pretendAwake() {
    output = '''
      mWakefulness=Awake
    ''';
  }

  static void pretendAsleep() {
    output = '''
      mWakefulness=Asleep
    ''';
  }

  static void pretendBatteryHealth(int batteryHealth) {
    output = '''
  health: $batteryHealth
    ''';
  }

  @override
  Future<String> shellEval(String command, List<String> arguments,
      {Map<String, String> env}) async {
    commandLog
        .add(CommandArgs(command: command, arguments: arguments, env: env));
    return output;
  }

  @override
  Future<Null> shellExec(String command, List<String> arguments,
      {Map<String, String> env}) async {
    commandLog
        .add(CommandArgs(command: command, arguments: arguments, env: env));
    dynamic exitError = exitErrorFactory();
    if (exitError != null) throw exitError;
  }
}

class FakeAndroidDeviceDiscovery extends AndroidDeviceDiscovery {
  FakeAndroidDeviceDiscovery() : super.testing();

  List<dynamic> _outputs;
  int _pos = 0;

  set outputs(List<dynamic> outputs) {
    _pos = 0;
    _outputs = outputs;
  }

  @override
  Future<String> deviceListOutput() async {
    _pos++;
    if (_outputs[_pos - 1] is String) {
      return _outputs[_pos - 1] as String;
    } else {
      throw _outputs[_pos - 1];
    }
  }

  @override
  void killAdbServer() async {}
}
