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

import '../android/android_device.dart';
import '../application_package.dart';
import '../base/common.dart';
import '../base/io.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../runner/flutter_command.dart';

class InstallCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
  InstallCommand() {
    requiresPubspecYaml();
    usesDeviceUserOption();
    usesDeviceTimeoutOption();
    argParser.addFlag('uninstall-only',
      negatable: true,
      defaultsTo: false,
      help: 'Uninstall the app if already on the device. Skip install.',
    );
  }

  @override
  final String name = 'install';

  @override
  final String description = 'Install a Flutter app on an attached device.';

  Device device;

  bool get uninstallOnly => boolArg('uninstall-only');
  String get userIdentifier => stringArg(FlutterOptions.kDeviceUser);

  @override
  Future<void> validateCommand() async {
    await super.validateCommand();
    device = await findTargetDevice();
    if (device == null) {
      throwToolExit('No target device found');
    }
    if (userIdentifier != null && device is! AndroidDevice) {
      throwToolExit('--${FlutterOptions.kDeviceUser} is only supported for Android');
    }
  }

  @override
  Future<FlutterCommandResult> runCommand() async {
    final ApplicationPackage package = await applicationPackages.getPackageForPlatform(
      await device.targetPlatform,
      null, // Build info isn't relevant for install, will use whatever bundle was built last.
    );

    if (uninstallOnly) {
      await _uninstallApp(package);
    } else {
      await _installApp(package);
    }
    return FlutterCommandResult.success();
  }

  Future<void> _uninstallApp(ApplicationPackage package) async {
    if (await device.isAppInstalled(package, userIdentifier: userIdentifier)) {
      globals.printStatus('Uninstalling $package from $device...');
      if (!await device.uninstallApp(package, userIdentifier: userIdentifier)) {
        globals.printError('Uninstalling old version failed');
      }
    } else {
      globals.printStatus('$package not found on $device, skipping uninstall');
    }
  }

  Future<void> _installApp(ApplicationPackage package) async {
    globals.printStatus('Installing $package to $device...');

    if (!await installApp(device, package, userIdentifier: userIdentifier)) {
      throwToolExit('Install failed');
    }
  }
}

Future<bool> installApp(
  Device device,
  ApplicationPackage package, {
  String userIdentifier,
  bool uninstall = true
}) async {
  if (package == null) {
    return false;
  }

  try {
    if (uninstall && await device.isAppInstalled(package, userIdentifier: userIdentifier)) {
      globals.printStatus('Uninstalling old version...');
      if (!await device.uninstallApp(package, userIdentifier: userIdentifier)) {
        globals.printError('Warning: uninstalling old version failed');
      }
    }
  } on ProcessException catch (e) {
    globals.printError('Error accessing device ${device.id}:\n${e.message}');
  }

  return device.installApp(package, userIdentifier: userIdentifier);
}
