/*
 * Copyright (C) 2015 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.
 */

package com.android.mtp;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.SystemClock;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;

/**
 * Static utility methods for testing.
 */
final class TestUtil {
    private TestUtil() {}

    /**
     * Requests permission for a MTP device and returns the first MTP device that has at least one
     * storage.
     */
    static UsbDevice setupMtpDevice(
            TestResultInstrumentation instrumentation,
            UsbManager usbManager,
            MtpManager manager) {
        while (true) {
            try {
                final UsbDevice device = findMtpDevice(usbManager, manager);
                waitForStorages(instrumentation, manager, device.getDeviceId());
                return device;
            } catch (IOException exp) {
                instrumentation.show(Objects.toString(exp.getMessage()));
                SystemClock.sleep(1000);
                // When the MTP device is Android, and it changes the USB device type from
                // "Charging" to "MTP", the device ID will be updated. We need to find a device
                // again.
                continue;
            }
        }
    }

    static void addTestDevice(MtpDatabase database) throws FileNotFoundException {
        database.getMapper().startAddingDocuments(null);
        database.getMapper().putDeviceDocument(new MtpDeviceRecord(
                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
                null));
        database.getMapper().stopAddingDocuments(null);
    }

    static void addTestStorage(MtpDatabase database, String parentId) throws FileNotFoundException {
        database.getMapper().startAddingDocuments(parentId);
        database.getMapper().putStorageDocuments(parentId, new MtpRoot[] {
                new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
        });
        database.getMapper().stopAddingDocuments(parentId);
    }

    private static UsbDevice findMtpDevice(
            UsbManager usbManager,
            MtpManager manager) throws IOException {
        final HashMap<String,UsbDevice> devices = usbManager.getDeviceList();
        if (devices.size() == 0) {
            throw new IOException("Device not found.");
        }
        final UsbDevice device = devices.values().iterator().next();
        // Tries to get ownership of the device in case that another application use it.
        if (usbManager.hasPermission(device)) {
            final UsbDeviceConnection connection = usbManager.openDevice(device);
            for (int i = 0; i < device.getInterfaceCount(); i++) {
                // Since the test runs real environment, we need to call claim interface with
                // force = true to rob interfaces from other applications.
                connection.claimInterface(device.getInterface(i), true);
                connection.releaseInterface(device.getInterface(i));
            }
            connection.close();
        }
        manager.openDevice(device.getDeviceId());
        return device;
    }

    private static void waitForStorages(
            TestResultInstrumentation instrumentation,
            MtpManager manager,
            int deviceId) throws IOException {
        while (true) {
            MtpDeviceRecord device = null;
            for (final MtpDeviceRecord deviceCandidate : manager.getDevices()) {
                if (deviceCandidate.deviceId == deviceId) {
                    device = deviceCandidate;
                    break;
                }
            }
            if (device == null) {
                throw new IOException("Device was detached.");
            }
            if (device.roots.length == 0) {
                instrumentation.show("Wait for storages.");
                SystemClock.sleep(1000);
                continue;
            }
            return;
        }
    }
}
