/*
 * Copyright 2019 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.
 */

/*
 * Defines utility inteface that is used by state machine/service to either send vendor specific AT
 * command or receive vendor specific response from the native stack.
 */
package com.android.bluetooth.hfpclient;

import android.bluetooth.BluetoothAssignedNumbers;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadsetClient;
import android.content.Intent;
import android.util.Log;

import com.android.bluetooth.Utils;

import java.util.HashMap;
import java.util.Map;

class VendorCommandResponseProcessor {

    private static final String TAG = "VendorCommandResponseProcessor";
    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);

    private final HeadsetClientService mService;
    private final NativeInterface mNativeInterface;

    // Keys are AT commands (without payload), and values are the company IDs.
    private static final Map<String, Integer> SUPPORTED_VENDOR_AT_COMMANDS;
    static {
        SUPPORTED_VENDOR_AT_COMMANDS = new HashMap<>();
        SUPPORTED_VENDOR_AT_COMMANDS.put(
                "+XAPL=",
                BluetoothAssignedNumbers.APPLE);
        SUPPORTED_VENDOR_AT_COMMANDS.put(
                "+IPHONEACCEV=",
                BluetoothAssignedNumbers.APPLE);
        SUPPORTED_VENDOR_AT_COMMANDS.put(
                "+APLSIRI?",
                BluetoothAssignedNumbers.APPLE);
        SUPPORTED_VENDOR_AT_COMMANDS.put(
                "+APLEFM",
                BluetoothAssignedNumbers.APPLE);
    }

    // Keys are AT events (without payload), and values are the company IDs.
    private static final Map<String, Integer> SUPPORTED_VENDOR_EVENTS;
    static {
        SUPPORTED_VENDOR_EVENTS = new HashMap<>();
        SUPPORTED_VENDOR_EVENTS.put(
                "+APLSIRI:",
                BluetoothAssignedNumbers.APPLE);
        SUPPORTED_VENDOR_EVENTS.put(
                "+XAPL=",
                BluetoothAssignedNumbers.APPLE);
    }

    VendorCommandResponseProcessor(HeadsetClientService context, NativeInterface nativeInterface) {
        mService = context;
        mNativeInterface = nativeInterface;
    }

    public boolean sendCommand(int vendorId, String atCommand, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processVendorCommand device is null");
            return false;
        }

        // Do not support more than one command at one line.
        // We simplify and say no ; allowed as well.
        int indexOfSemicolon = atCommand.indexOf(';');
        if (indexOfSemicolon > 0) {
            Log.e(TAG, "Do not support ; and more than one command:"
                    + atCommand);
            return false;
        }

        // Get command word
        int indexOfEqual = atCommand.indexOf('=');
        int indexOfQuestionMark = atCommand.indexOf('?');
        String commandWord;
        if (indexOfEqual > 0) {
            commandWord = atCommand.substring(0, indexOfEqual + 1);
        } else if (indexOfQuestionMark > 0) {
            commandWord = atCommand.substring(0, indexOfQuestionMark + 1);
        } else {
            commandWord = atCommand;
        }

        // replace all white spaces
        commandWord = commandWord.replaceAll("\\s+", "");

        if (SUPPORTED_VENDOR_AT_COMMANDS.get(commandWord) != (Integer) (vendorId)) {
            Log.e(TAG, "Invalid command " + atCommand + ", " + vendorId + ". Cand="
                    + commandWord);
            return false;
        }

        if (!mNativeInterface.sendATCmd(Utils.getBytesFromAddress(device.getAddress()),
                                        HeadsetClientHalConstants
                                        .HANDSFREECLIENT_AT_CMD_VENDOR_SPECIFIC_CMD,
                                        0, 0, atCommand)) {
            Log.e(TAG, "Failed to send vendor specific at command");
            return false;
        }
        logD("Send vendor command: " + atCommand);
        return true;
    }

    public boolean processEvent(String atString, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processVendorEvent device is null");
            return false;
        }

        // Get event code
        int indexOfEqual = atString.indexOf('=');
        int indexOfColon = atString.indexOf(':');
        String eventCode;
        if (indexOfEqual > 0) {
            eventCode = atString.substring(0, indexOfEqual + 1);
        } else if (indexOfColon > 0) {
            eventCode = atString.substring(0, indexOfColon + 1);
        } else {
            eventCode = atString;
        }

        // replace all white spaces
        eventCode = eventCode.replaceAll("\\s+", "");

        Integer vendorId = SUPPORTED_VENDOR_EVENTS.get(eventCode);
        if (vendorId == null) {
            Log.e(TAG, "Invalid response: " + atString + ". " + eventCode);
            return false;
        }
        broadcastVendorSpecificEventIntent(vendorId, eventCode, atString, device);
        logD("process vendor event " + vendorId + ", " + eventCode + ", "
                + atString + " for device" + device);
        return true;
    }

    private void broadcastVendorSpecificEventIntent(int vendorId, String vendorEventCode,
            String vendorResponse, BluetoothDevice device) {
        logD("broadcastVendorSpecificEventIntent(" + vendorResponse + ")");
        Intent intent = new Intent(BluetoothHeadsetClient
                                   .ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT);
        intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_ID, vendorId);
        intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_CODE, vendorEventCode);
        intent.putExtra(BluetoothHeadsetClient.EXTRA_VENDOR_EVENT_FULL_ARGS, vendorResponse);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        mService.sendBroadcast(intent, HeadsetClientService.BLUETOOTH_PERM);
    }

    private void logD(String msg) {
        if (DBG) {
            Log.d(TAG, msg);
        }
    }
}
