// Copyright (C) 2022 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {assertExists} from '../../../base/logging';
import {getErrorMessage} from '../../errors';
import {RECORDING_V2_FLAG} from '../../feature_flags';
import {AdbKeyManager} from '../auth/adb_key_manager';
import {RecordingError} from '../recording_error_handling';
import {
  OnTargetChangeCallback,
  RecordingTargetV2,
  TargetFactory,
} from '../recording_interfaces_v2';
import {ADB_DEVICE_FILTER, findInterfaceAndEndpoint} from '../recording_utils';
import {targetFactoryRegistry} from '../target_factory_registry';
import {AndroidWebusbTarget} from '../targets/android_webusb_target';

export const ANDROID_WEBUSB_TARGET_FACTORY = 'AndroidWebusbTargetFactory';
const SERIAL_NUMBER_ISSUE = 'an invalid serial number';
const ADB_INTERFACE_ISSUE = 'an incompatible adb interface';

interface DeviceValidity {
  isValid: boolean;
  issues: string[];
}

function createDeviceErrorMessage(device: USBDevice, issue: string): string {
  const productName = device.productName;
  return `USB device${productName ? ' ' + productName : ''} has ${issue}`;
}

export class AndroidWebusbTargetFactory implements TargetFactory {
  readonly kind = ANDROID_WEBUSB_TARGET_FACTORY;
  onTargetChange: OnTargetChangeCallback = () => {};
  private recordingProblems: string[] = [];
  private targets: Map<string, AndroidWebusbTarget> =
      new Map<string, AndroidWebusbTarget>();
  // AdbKeyManager should only be instantiated once, so we can use the same key
  // for all devices.
  private keyManager: AdbKeyManager = new AdbKeyManager();

  constructor(private usb: USB) {
    this.init();
  }

  getName() {
    return 'Android WebUsb';
  }

  listTargets(): RecordingTargetV2[] {
    return Array.from(this.targets.values());
  }

  listRecordingProblems(): string[] {
    return this.recordingProblems;
  }

  async connectNewTarget(): Promise<RecordingTargetV2> {
    let device: USBDevice;
    try {
      device = await this.usb.requestDevice({filters: [ADB_DEVICE_FILTER]});
    } catch (e) {
      throw new RecordingError(getErrorMessage(e));
    }

    const deviceValid = this.checkDeviceValidity(device);
    if (!deviceValid.isValid) {
      throw new RecordingError(deviceValid.issues.join('\n'));
    }

    const androidTarget =
        new AndroidWebusbTarget(device, this.keyManager, this.onTargetChange);
    this.targets.set(assertExists(device.serialNumber), androidTarget);
    return androidTarget;
  }

  setOnTargetChange(onTargetChange: OnTargetChangeCallback) {
    this.onTargetChange = onTargetChange;
  }

  private async init() {
    for (const device of await this.usb.getDevices()) {
      if (this.checkDeviceValidity(device).isValid) {
        this.targets.set(
            assertExists(device.serialNumber),
            new AndroidWebusbTarget(
                device, this.keyManager, this.onTargetChange));
      }
    }

    this.usb.addEventListener('connect', (ev: USBConnectionEvent) => {
      if (this.checkDeviceValidity(ev.device).isValid) {
        this.targets.set(
            assertExists(ev.device.serialNumber),
            new AndroidWebusbTarget(
                ev.device, this.keyManager, this.onTargetChange));
        this.onTargetChange();
      }
    });

    this.usb.addEventListener('disconnect', async (ev: USBConnectionEvent) => {
      // We don't check device validity when disconnecting because if the device
      // is invalid we would not have connected in the first place.
      const serialNumber = assertExists(ev.device.serialNumber);
      await assertExists(this.targets.get(serialNumber))
          .disconnect(`Device with serial ${serialNumber} was disconnected.`);
      this.targets.delete(serialNumber);
      this.onTargetChange();
    });
  }

  private checkDeviceValidity(device: USBDevice): DeviceValidity {
    const deviceValidity: DeviceValidity = {isValid: true, issues: []};
    if (!device.serialNumber) {
      deviceValidity.issues.push(
          createDeviceErrorMessage(device, SERIAL_NUMBER_ISSUE));
      deviceValidity.isValid = false;
    }
    if (!findInterfaceAndEndpoint(device)) {
      deviceValidity.issues.push(
          createDeviceErrorMessage(device, ADB_INTERFACE_ISSUE));
      deviceValidity.isValid = false;
    }
    this.recordingProblems.push(...deviceValidity.issues);
    return deviceValidity;
  }
}

// We only want to instantiate this class if:
// 1. The browser implements the USB functionality.
// 2. Recording V2 is enabled.
if (navigator.usb && RECORDING_V2_FLAG.get()) {
  targetFactoryRegistry.register(new AndroidWebusbTargetFactory(navigator.usb));
}
