/*
 * Copyright (C) 2016 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 android.car.usb.handler;

import android.annotation.Nullable;
import android.car.IUsbAoapSupportCheckService;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;

import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/** Resolves supported handlers for USB device. */
public final class UsbDeviceHandlerResolver {
    private static final String TAG = UsbDeviceHandlerResolver.class.getSimpleName();
    private static final boolean LOCAL_LOGD = true;

    /**
     * Callbacks for device resolver.
     */
    public interface UsbDeviceHandlerResolverCallback {
        /** Handlers are resolved */
        void onHandlersResolveCompleted(
                UsbDevice device, List<UsbDeviceSettings> availableSettings);
        /** Device was dispatched */
        void onDeviceDispatched();
    }

    private final UsbManager mUsbManager;
    private final PackageManager mPackageManager;
    private final UsbDeviceHandlerResolverCallback mDeviceCallback;
    private final Context mContext;
    private final HandlerThread mHandlerThread;
    private final UsbDeviceResolverHandler mHandler;

    private class DeviceContext {
        public final UsbDevice usbDevice;
        @Nullable public final UsbDeviceConnection connection;
        public final UsbDeviceSettings settings;
        public final List<UsbDeviceSettings> activeDeviceSettings;
        public final Queue<Pair<ResolveInfo, DeviceFilter>> mActiveDeviceOptions =
                new LinkedList<>();

        private volatile IUsbAoapSupportCheckService mUsbAoapSupportCheckService;
        private final ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName className, IBinder service) {
                Log.i(TAG, "onServiceConnected: " + className);
                mUsbAoapSupportCheckService = IUsbAoapSupportCheckService.Stub.asInterface(service);
                mHandler.requestOnServiceConnectionStateChanged(DeviceContext.this);
            }

            @Override
            public void onServiceDisconnected(ComponentName className) {
                Log.i(TAG, "onServiceDisconnected: " + className);
                mUsbAoapSupportCheckService = null;
                mHandler.requestOnServiceConnectionStateChanged(DeviceContext.this);
            }
        };

        public DeviceContext(UsbDevice usbDevice, UsbDeviceSettings settings,
                List<UsbDeviceSettings> activeDeviceSettings) {
            this.usbDevice = usbDevice;
            this.settings = settings;
            this.activeDeviceSettings = activeDeviceSettings;
            connection = UsbUtil.openConnection(mUsbManager, usbDevice);
        }
    }

    // This class is used to describe a USB device.
    // When used in HashMaps all values must be specified,
    // but wildcards can be used for any of the fields in
    // the package meta-data.
    private static class DeviceFilter {
        // USB Vendor ID (or -1 for unspecified)
        public final int mVendorId;
        // USB Product ID (or -1 for unspecified)
        public final int mProductId;
        // USB device or interface class (or -1 for unspecified)
        public final int mClass;
        // USB device subclass (or -1 for unspecified)
        public final int mSubclass;
        // USB device protocol (or -1 for unspecified)
        public final int mProtocol;
        // USB device manufacturer name string (or null for unspecified)
        public final String mManufacturerName;
        // USB device product name string (or null for unspecified)
        public final String mProductName;
        // USB device serial number string (or null for unspecified)
        public final String mSerialNumber;

        // USB device in AOAP mode manufacturer
        public final String mAoapManufacturer;
        // USB device in AOAP mode model
        public final String mAoapModel;
        // USB device in AOAP mode description string
        public final String mAoapDescription;
        // USB device in AOAP mode version
        public final String mAoapVersion;
        // USB device in AOAP mode URI
        public final String mAoapUri;
        // USB device in AOAP mode serial
        public final String mAoapSerial;
        // USB device in AOAP mode verification service
        public final String mAoapService;

        DeviceFilter(int vid, int pid, int clasz, int subclass, int protocol,
                            String manufacturer, String product, String serialnum,
                            String aoapManufacturer, String aoapModel, String aoapDescription,
                            String aoapVersion, String aoapUri, String aoapSerial,
                            String aoapService) {
            mVendorId = vid;
            mProductId = pid;
            mClass = clasz;
            mSubclass = subclass;
            mProtocol = protocol;
            mManufacturerName = manufacturer;
            mProductName = product;
            mSerialNumber = serialnum;

            mAoapManufacturer = aoapManufacturer;
            mAoapModel = aoapModel;
            mAoapDescription = aoapDescription;
            mAoapVersion = aoapVersion;
            mAoapUri = aoapUri;
            mAoapSerial = aoapSerial;
            mAoapService = aoapService;
        }

        DeviceFilter(UsbDevice device) {
            mVendorId = device.getVendorId();
            mProductId = device.getProductId();
            mClass = device.getDeviceClass();
            mSubclass = device.getDeviceSubclass();
            mProtocol = device.getDeviceProtocol();
            mManufacturerName = device.getManufacturerName();
            mProductName = device.getProductName();
            mSerialNumber = device.getSerialNumber();
            mAoapManufacturer = null;
            mAoapModel = null;
            mAoapDescription = null;
            mAoapVersion = null;
            mAoapUri = null;
            mAoapSerial = null;
            mAoapService = null;
        }

        public static DeviceFilter read(XmlPullParser parser, boolean aoapData) {
            int vendorId = -1;
            int productId = -1;
            int deviceClass = -1;
            int deviceSubclass = -1;
            int deviceProtocol = -1;
            String manufacturerName = null;
            String productName = null;
            String serialNumber = null;

            String aoapManufacturer = null;
            String aoapModel = null;
            String aoapDescription = null;
            String aoapVersion = null;
            String aoapUri = null;
            String aoapSerial = null;
            String aoapService = null;

            int count = parser.getAttributeCount();
            for (int i = 0; i < count; i++) {
                String name = parser.getAttributeName(i);
                String value = parser.getAttributeValue(i);
                // Attribute values are ints or strings
                if (!aoapData && "manufacturer-name".equals(name)) {
                    manufacturerName = value;
                } else if (!aoapData && "product-name".equals(name)) {
                    productName = value;
                } else if (!aoapData && "serial-number".equals(name)) {
                    serialNumber = value;
                } else if (aoapData && "manufacturer".equals(name)) {
                    aoapManufacturer = value;
                } else if (aoapData && "model".equals(name)) {
                    aoapModel = value;
                } else if (aoapData && "description".equals(name)) {
                    aoapDescription = value;
                } else if (aoapData && "version".equals(name)) {
                    aoapVersion = value;
                } else if (aoapData && "uri".equals(name)) {
                    aoapUri = value;
                } else if (aoapData && "serial".equals(name)) {
                    aoapSerial = value;
                } else if (aoapData && "service".equals(name)) {
                    aoapService = value;
                } else if (!aoapData) {
                    int intValue = -1;
                    int radix = 10;
                    if (value != null && value.length() > 2 && value.charAt(0) == '0'
                            && (value.charAt(1) == 'x' || value.charAt(1) == 'X')) {
                        // allow hex values starting with 0x or 0X
                        radix = 16;
                        value = value.substring(2);
                    }
                    try {
                        intValue = Integer.parseInt(value, radix);
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "invalid number for field " + name, e);
                        continue;
                    }
                    if ("vendor-id".equals(name)) {
                        vendorId = intValue;
                    } else if ("product-id".equals(name)) {
                        productId = intValue;
                    } else if ("class".equals(name)) {
                        deviceClass = intValue;
                    } else if ("subclass".equals(name)) {
                        deviceSubclass = intValue;
                    } else if ("protocol".equals(name)) {
                        deviceProtocol = intValue;
                    }
                }
            }
            return new DeviceFilter(vendorId, productId,
                                    deviceClass, deviceSubclass, deviceProtocol,
                                    manufacturerName, productName, serialNumber, aoapManufacturer,
                                    aoapModel, aoapDescription, aoapVersion, aoapUri, aoapSerial,
                                    aoapService);
        }

        private boolean matches(int clasz, int subclass, int protocol) {
            return ((mClass == -1 || clasz == mClass)
                    && (mSubclass == -1 || subclass == mSubclass)
                    && (mProtocol == -1 || protocol == mProtocol));
        }

        public boolean matches(UsbDevice device) {
            if (mVendorId != -1 && device.getVendorId() != mVendorId) {
                return false;
            }
            if (mProductId != -1 && device.getProductId() != mProductId) {
                return false;
            }
            if (mManufacturerName != null && device.getManufacturerName() == null) {
                return false;
            }
            if (mProductName != null && device.getProductName() == null) {
                return false;
            }
            if (mSerialNumber != null && device.getSerialNumber() == null) {
                return false;
            }
            if (mManufacturerName != null && device.getManufacturerName() != null
                    && !mManufacturerName.equals(device.getManufacturerName())) {
                return false;
            }
            if (mProductName != null && device.getProductName() != null
                    && !mProductName.equals(device.getProductName())) {
                return false;
            }
            if (mSerialNumber != null && device.getSerialNumber() != null
                    && !mSerialNumber.equals(device.getSerialNumber())) {
                return false;
            }

            // check device class/subclass/protocol
            if (matches(device.getDeviceClass(), device.getDeviceSubclass(),
                        device.getDeviceProtocol())) {
                return true;
            }

            // if device doesn't match, check the interfaces
            int count = device.getInterfaceCount();
            for (int i = 0; i < count; i++) {
                UsbInterface intf = device.getInterface(i);
                if (matches(intf.getInterfaceClass(), intf.getInterfaceSubclass(),
                            intf.getInterfaceProtocol())) {
                    return true;
                }
            }

            return false;
        }

        @Override
        public boolean equals(Object obj) {
            // can't compare if we have wildcard strings
            if (mVendorId == -1 || mProductId == -1
                    || mClass == -1 || mSubclass == -1 || mProtocol == -1) {
                return false;
            }
            if (obj instanceof DeviceFilter) {
                DeviceFilter filter = (DeviceFilter) obj;

                if (filter.mVendorId != mVendorId
                        || filter.mProductId != mProductId
                        || filter.mClass != mClass
                        || filter.mSubclass != mSubclass
                        || filter.mProtocol != mProtocol) {
                    return false;
                }
                if ((filter.mManufacturerName != null && mManufacturerName == null)
                        || (filter.mManufacturerName == null && mManufacturerName != null)
                        || (filter.mProductName != null && mProductName == null)
                        || (filter.mProductName == null && mProductName != null)
                        || (filter.mSerialNumber != null && mSerialNumber == null)
                        || (filter.mSerialNumber == null && mSerialNumber != null)) {
                    return false;
                }
                if  ((filter.mManufacturerName != null && mManufacturerName != null
                          && !mManufacturerName.equals(filter.mManufacturerName))
                          || (filter.mProductName != null && mProductName != null
                          && !mProductName.equals(filter.mProductName))
                          || (filter.mSerialNumber != null && mSerialNumber != null
                          && !mSerialNumber.equals(filter.mSerialNumber))) {
                    return false;
                }
                return true;
            }
            if (obj instanceof UsbDevice) {
                UsbDevice device = (UsbDevice) obj;
                if (device.getVendorId() != mVendorId
                        || device.getProductId() != mProductId
                        || device.getDeviceClass() != mClass
                        || device.getDeviceSubclass() != mSubclass
                        || device.getDeviceProtocol() != mProtocol) {
                    return false;
                }
                if ((mManufacturerName != null && device.getManufacturerName() == null)
                        || (mManufacturerName == null && device.getManufacturerName() != null)
                        || (mProductName != null && device.getProductName() == null)
                        || (mProductName == null && device.getProductName() != null)
                        || (mSerialNumber != null && device.getSerialNumber() == null)
                        || (mSerialNumber == null && device.getSerialNumber() != null)) {
                    return false;
                }
                if ((device.getManufacturerName() != null
                        && !mManufacturerName.equals(device.getManufacturerName()))
                        || (device.getProductName() != null
                        && !mProductName.equals(device.getProductName()))
                        || (device.getSerialNumber() != null
                        && !mSerialNumber.equals(device.getSerialNumber()))) {
                    return false;
                }
                return true;
            }
            return false;
        }

        @Override
        public int hashCode() {
            return (((mVendorId << 16) | mProductId)
                    ^ ((mClass << 16) | (mSubclass << 8) | mProtocol));
        }

        @Override
        public String toString() {
            return "DeviceFilter[mVendorId=" + mVendorId + ",mProductId=" + mProductId
                    + ",mClass=" + mClass + ",mSubclass=" + mSubclass
                    + ",mProtocol=" + mProtocol + ",mManufacturerName=" + mManufacturerName
                    + ",mProductName=" + mProductName + ",mSerialNumber=" + mSerialNumber + "]";
        }
    }

    public UsbDeviceHandlerResolver(UsbManager manager, Context context,
            UsbDeviceHandlerResolverCallback deviceListener) {
        mUsbManager = manager;
        mContext = context;
        mDeviceCallback = deviceListener;
        mHandlerThread = new HandlerThread(TAG);
        mHandlerThread.start();
        mHandler = new UsbDeviceResolverHandler(mHandlerThread.getLooper());
        mPackageManager = context.getPackageManager();
    }

    /**
     * Releases current object.
     */
    public void release() {
        if (mHandlerThread != null) {
            mHandlerThread.quitSafely();
        }
    }

    /**
     * Resolves handlers for USB device.
     */
    public void resolve(UsbDevice device) {
        mHandler.requestResolveHandlers(device);
    }

    /**
     * Dispatches device to component.
     */
    public boolean dispatch(UsbDevice device, ComponentName component, boolean inAoap) {
        if (LOCAL_LOGD) {
            Log.d(TAG, "dispatch: " + device + " component: " + component + " inAoap: " + inAoap);
        }

        ActivityInfo activityInfo;
        try {
            activityInfo = mPackageManager.getActivityInfo(component, PackageManager.GET_META_DATA);
        } catch (NameNotFoundException e) {
            Log.e(TAG, "Activity not found: " + component);
            return false;
        }

        Intent intent = createDeviceAttachedIntent(device);
        if (inAoap) {
            if (AoapInterface.isDeviceInAoapMode(device)) {
                mDeviceCallback.onDeviceDispatched();
            } else {
                DeviceFilter filter =
                        packageMatches(activityInfo, intent.getAction(), device, true);
                if (filter != null) {
                    requestAoapSwitch(device, filter);
                    return true;
                }
            }
        }

        intent.setComponent(component);
        mUsbManager.grantPermission(device, activityInfo.applicationInfo.uid);

        mContext.startActivity(intent);
        mHandler.requestCompleteDeviceDispatch();
        return true;
    }

    private static Intent createDeviceAttachedIntent(UsbDevice device) {
        Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
    }

    private void doHandleResolveHandlers(UsbDevice device) {
        if (LOCAL_LOGD) {
            Log.d(TAG, "doHandleResolveHandlers: " + device);
        }

        Intent intent = createDeviceAttachedIntent(device);
        List<Pair<ResolveInfo, DeviceFilter>> matches = getDeviceMatches(device, intent, false);
        if (LOCAL_LOGD) {
            Log.d(TAG, "matches size: " + matches.size());
        }
        List<UsbDeviceSettings> settings = new ArrayList<>(matches.size());
        for (Pair<ResolveInfo, DeviceFilter> info : matches) {
            UsbDeviceSettings setting = UsbDeviceSettings.constructSettings(device);
            setting.setHandler(
                    new ComponentName(
                            info.first.activityInfo.packageName, info.first.activityInfo.name));
            settings.add(setting);
        }
        DeviceContext deviceContext =
                new DeviceContext(device, UsbDeviceSettings.constructSettings(device), settings);
        if (deviceContext.connection != null
                && AoapInterface.isSupported(mContext, device, deviceContext.connection)) {
            deviceContext.mActiveDeviceOptions.addAll(getDeviceMatches(device, intent, true));
            queryNextAoapHandler(deviceContext);
        } else {
            deviceProbingComplete(deviceContext);
        }
    }

    private void queryNextAoapHandler(DeviceContext context) {
        Pair<ResolveInfo, DeviceFilter> option = context.mActiveDeviceOptions.peek();
        if (option == null) {
            Log.w(TAG, "No more options left.");
            deviceProbingComplete(context);
            return;
        }
        Intent serviceIntent = new Intent();
        serviceIntent.setComponent(ComponentName.unflattenFromString(option.second.mAoapService));
        boolean bound = mContext.bindService(serviceIntent, context.mServiceConnection,
                Context.BIND_AUTO_CREATE);
        if (bound) {
            mHandler.requestServiceConnectionTimeout();
        } else {
            if (LOCAL_LOGD) {
                Log.d(TAG, "Failed to bind to the service");
            }
            context.mActiveDeviceOptions.poll();
            queryNextAoapHandler(context);
        }
    }

    private void requestAoapSwitch(UsbDevice device, DeviceFilter filter) {
        UsbDeviceConnection connection = UsbUtil.openConnection(mUsbManager, device);
        if (connection == null) {
            Log.e(TAG, "Failed to connect to usb device.");
            return;
        }
        try {
            UsbUtil.sendAoapAccessoryStart(
                    connection,
                    filter.mAoapManufacturer,
                    filter.mAoapModel,
                    filter.mAoapDescription,
                    filter.mAoapVersion,
                    filter.mAoapUri,
                    filter.mAoapSerial);
        } catch (IOException e) {
            Log.w(TAG, "Failed to switch device into AOAP mode", e);
        }
        connection.close();
    }

    private void deviceProbingComplete(DeviceContext context) {
        if (LOCAL_LOGD) {
            Log.d(TAG, "deviceProbingComplete");
        }
        mDeviceCallback.onHandlersResolveCompleted(context.usbDevice, context.activeDeviceSettings);
    }

    private void doHandleServiceConnectionStateChanged(DeviceContext context) {
        if (LOCAL_LOGD) {
            Log.d(TAG, "doHandleServiceConnectionStateChanged: "
                    + context.mUsbAoapSupportCheckService);
        }
        if (context.mUsbAoapSupportCheckService != null) {
            boolean deviceSupported = false;
            try {
                deviceSupported =
                        context.mUsbAoapSupportCheckService.isDeviceSupported(context.usbDevice);
            } catch (RemoteException e) {
                Log.e(TAG, "Call to remote service failed", e);
            }
            if (deviceSupported) {
                Pair<ResolveInfo, DeviceFilter> option = context.mActiveDeviceOptions.peek();

                UsbDeviceSettings setting = UsbDeviceSettings.constructSettings(context.settings);
                setting.setHandler(
                        new ComponentName(
                            option.first.activityInfo.packageName, option.first.activityInfo.name));
                setting.setAoap(true);
                context.activeDeviceSettings.add(setting);
            }
            mContext.unbindService(context.mServiceConnection);
        }
        context.mActiveDeviceOptions.poll();
        queryNextAoapHandler(context);
    }

    private List<Pair<ResolveInfo, DeviceFilter>> getDeviceMatches(
            UsbDevice device, Intent intent, boolean forAoap) {
        List<Pair<ResolveInfo, DeviceFilter>> matches = new ArrayList<>();
        List<ResolveInfo> resolveInfos =
                mPackageManager.queryIntentActivities(intent, PackageManager.GET_META_DATA);
        for (ResolveInfo resolveInfo : resolveInfos) {
            DeviceFilter filter = packageMatches(resolveInfo.activityInfo,
                    intent.getAction(), device, forAoap);
            if (filter != null) {
                matches.add(Pair.create(resolveInfo, filter));
            }
        }
        return matches;
    }

    private DeviceFilter packageMatches(ActivityInfo ai, String metaDataName, UsbDevice device,
            boolean forAoap) {
        if (LOCAL_LOGD) {
            Log.d(TAG, "packageMatches ai: " + ai + "metaDataName: " + metaDataName + " forAoap: "
                    + forAoap);
        }
        String filterTagName = forAoap ? "usb-aoap-accessory" : "usb-device";
        XmlResourceParser parser = null;
        try {
            parser = ai.loadXmlMetaData(mPackageManager, metaDataName);
            if (parser == null) {
                Log.w(TAG, "no meta-data for " + ai);
                return null;
            }

            XmlUtils.nextElement(parser);
            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                String tagName = parser.getName();
                if (device != null && filterTagName.equals(tagName)) {
                    DeviceFilter filter = DeviceFilter.read(parser, forAoap);
                    if (forAoap || filter.matches(device)) {
                        return filter;
                    }
                }
                XmlUtils.nextElement(parser);
            }
        } catch (Exception e) {
            Log.w(TAG, "Unable to load component info " + ai.toString(), e);
        } finally {
            if (parser != null) parser.close();
        }
        return null;
    }

    private class UsbDeviceResolverHandler extends Handler {
        private static final int MSG_RESOLVE_HANDLERS = 0;
        private static final int MSG_SERVICE_CONNECTION_STATE_CHANGE = 1;
        private static final int MSG_SERVICE_CONNECTION_TIMEOUT = 2;
        private static final int MSG_COMPLETE_DISPATCH = 3;

        private static final long CONNECT_TIMEOUT_MS = 5000;

        private UsbDeviceResolverHandler(Looper looper) {
            super(looper);
        }

        public void requestResolveHandlers(UsbDevice device) {
            Message msg = obtainMessage(MSG_RESOLVE_HANDLERS, device);
            sendMessage(msg);
        }

        public void requestOnServiceConnectionStateChanged(DeviceContext deviceContext) {
            sendMessage(obtainMessage(MSG_SERVICE_CONNECTION_STATE_CHANGE, deviceContext));
        }

        public void requestServiceConnectionTimeout() {
            sendEmptyMessageDelayed(MSG_SERVICE_CONNECTION_TIMEOUT, CONNECT_TIMEOUT_MS);
        }

        public void requestCompleteDeviceDispatch() {
            sendEmptyMessage(MSG_COMPLETE_DISPATCH);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_RESOLVE_HANDLERS:
                    doHandleResolveHandlers((UsbDevice) msg.obj);
                    break;
                case MSG_SERVICE_CONNECTION_STATE_CHANGE:
                    removeMessages(MSG_SERVICE_CONNECTION_TIMEOUT);
                    doHandleServiceConnectionStateChanged((DeviceContext) msg.obj);
                    break;
                case MSG_SERVICE_CONNECTION_TIMEOUT:
                    Log.i(TAG, "Service connection timeout");
                    doHandleServiceConnectionStateChanged(null);
                    break;
                case MSG_COMPLETE_DISPATCH:
                    mDeviceCallback.onDeviceDispatched();
                    break;
                default:
                    Log.w(TAG, "Unsupported message: " + msg);
            }
        }
    }
}
