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


package com.android.internal.telephony;

import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.net.Uri;
import android.telecom.PhoneAccount;
import android.telephony.SmsManager;
import android.telephony.SubscriptionInfo;
import android.util.Log;


/**
 * BtSmsInterfaceManager to provide a mechanism for sending SMS over Bluetooth
 */
public class BtSmsInterfaceManager {

    private static final String LOG_TAG = "BtSmsInterfaceManager";

    /**
     * Sends text through connected Bluetooth device
     */
    public void sendText(Context context, String destAddr, String text, PendingIntent sentIntent,
            PendingIntent deliveryIntent, SubscriptionInfo info) {
        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter == null) {
            // No bluetooth service on this platform?
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_NO_BLUETOOTH_SERVICE);
            return;
        }
        BluetoothDevice device = btAdapter.getRemoteDevice(info.getIccId());
        if (device == null) {
            Log.d(LOG_TAG, "Bluetooth device addr invalid: " + info.getIccId());
            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS);
            return;
        }
        btAdapter.getProfileProxy(context.getApplicationContext(),
                new MapMessageSender(destAddr, text, device, sentIntent, deliveryIntent),
                BluetoothProfile.MAP_CLIENT);
    }

    private void sendErrorInPendingIntent(PendingIntent intent, int errorCode) {
        if (intent == null) {
            return;
        }
        try {
            intent.send(errorCode);
        } catch (PendingIntent.CanceledException e) {
            // PendingIntent is cancelled. ignore sending this error code back to
            // caller.
            Log.d(LOG_TAG, "PendingIntent.CanceledException: " + e.getMessage());
        }
    }

    private class MapMessageSender implements BluetoothProfile.ServiceListener {

        final Uri[] mDestAddr;
        private String mMessage;
        final BluetoothDevice mDevice;
        final PendingIntent mSentIntent;
        final PendingIntent mDeliveryIntent;

        MapMessageSender(final String destAddr, final String message, final BluetoothDevice device,
                final PendingIntent sentIntent, final PendingIntent deliveryIntent) {
            super();
            mDestAddr = new Uri[]{new Uri.Builder()
                    .appendPath(destAddr)
                    .scheme(PhoneAccount.SCHEME_TEL)
                    .build()};
            mMessage = message;
            mDevice = device;
            mSentIntent = sentIntent;
            mDeliveryIntent = deliveryIntent;
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            Log.d(LOG_TAG, "Service connected");
            if (profile != BluetoothProfile.MAP_CLIENT) {
                return;
            }
            // Comment out the method for mainline (b/143848423). The profile is not for a phone,
            // so it will not be enabled.
/*            BluetoothMapClient mapProfile = (BluetoothMapClient) proxy;
            if (mMessage != null) {
                Log.d(LOG_TAG, "Sending message thru bluetooth");
                mapProfile.sendMessage(mDevice, mDestAddr, mMessage, mSentIntent, mDeliveryIntent);
                mMessage = null;
            }
            BluetoothAdapter.getDefaultAdapter()
                    .closeProfileProxy(BluetoothProfile.MAP_CLIENT, mapProfile);*/
            if (mMessage != null) {
                throw new RuntimeException("Can't send message through BluetoothMapClient");
            }
        }

        @Override
        public void onServiceDisconnected(int profile) {
            if (mMessage != null) {
                Log.d(LOG_TAG, "Bluetooth disconnected before sending the message");
                sendErrorInPendingIntent(mSentIntent, SmsManager.RESULT_BLUETOOTH_DISCONNECTED);
                mMessage = null;
            }
        }
    }
}
