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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;

import com.android.internal.os.SomeArgs;
import com.android.internal.telecom.ICallRedirectionAdapter;
import com.android.internal.telecom.ICallRedirectionService;

/**
 * This service can be implemented to interact between Telecom and its implementor
 * for making outgoing call with optional redirection/cancellation purposes.
 *
 * <p>
 * Below is an example manifest registration for a {@code CallRedirectionService}.
 * <pre>
 * {@code
 * <service android:name="your.package.YourCallRedirectionServiceImplementation"
 *          android:permission="android.permission.BIND_REDIRECTION_SERVICE">
 *      <intent-filter>
 *          <action android:name="android.telecom.CallRedirectionService"/>
 *      </intent-filter>
 * </service>
 * }
 * </pre>
 */
public abstract class CallRedirectionService extends Service {
    /**
     * The {@link Intent} that must be declared as handled by the service.
     */
    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
    public static final String SERVICE_INTERFACE = "android.telecom.CallRedirectionService";

    /**
     * An adapter to inform Telecom the response from the implementor of the Call
     * Redirection service
     */
    private ICallRedirectionAdapter mCallRedirectionAdapter;

    /**
     * Telecom calls this method once upon binding to a {@link CallRedirectionService} to inform
     * it of a new outgoing call which is being placed. Telecom does not request to redirect
     * emergency calls and does not request to redirect calls with gateway information.
     *
     * <p>Telecom will cancel the call if Telecom does not receive a response in 5 seconds from
     * the implemented {@link CallRedirectionService} set by users.
     *
     * <p>The implemented {@link CallRedirectionService} can call {@link #placeCallUnmodified()},
     * {@link #redirectCall(Uri, PhoneAccountHandle, boolean)}, and {@link #cancelCall()} only
     * from here. Calls to these methods are assumed by the Telecom framework to be the response
     * for the phone call for which {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)} was
     * invoked by Telecom. The Telecom framework will only invoke
     * {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)} once each time it binds to a
     * {@link CallRedirectionService}.
     *
     * @param handle the phone number dialed by the user, represented in E.164 format if possible
     * @param initialPhoneAccount the {@link PhoneAccountHandle} on which the call will be placed.
     * @param allowInteractiveResponse a boolean to tell if the implemented
     *                                 {@link CallRedirectionService} should allow interactive
     *                                 responses with users. Will be {@code false} if, for example
     *                                 the device is in car mode and the user would not be able to
     *                                 interact with their device.
     */
    public abstract void onPlaceCall(@NonNull Uri handle,
                                     @NonNull PhoneAccountHandle initialPhoneAccount,
                                     boolean allowInteractiveResponse);

    /**
     * The implemented {@link CallRedirectionService} calls this method to response a request
     * received via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)} to inform Telecom that
     * no changes are required to the outgoing call, and that the call should be placed as-is.
     *
     * <p>This can only be called from implemented
     * {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}. The response corresponds to the
     * latest request via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}.
     *
     */
    public final void placeCallUnmodified() {
        try {
            mCallRedirectionAdapter.placeCallUnmodified();
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }

    /**
     * The implemented {@link CallRedirectionService} calls this method to response a request
     * received via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)} to inform Telecom that
     * changes are required to the phone number or/and {@link PhoneAccountHandle} for the outgoing
     * call. Telecom will cancel the call if the implemented {@link CallRedirectionService}
     * replies Telecom a handle for an emergency number.
     *
     * <p>This can only be called from implemented
     * {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}. The response corresponds to the
     * latest request via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}.
     *
     * @param gatewayUri the gateway uri for call redirection.
     * @param targetPhoneAccount the {@link PhoneAccountHandle} to use when placing the call.
     * @param confirmFirst Telecom will ask users to confirm the redirection via a yes/no dialog
     *                     if the confirmFirst is true, and if the redirection request of this
     *                     response was sent with a true flag of allowInteractiveResponse via
     *                     {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}
     */
    public final void redirectCall(@NonNull Uri gatewayUri,
                                   @NonNull PhoneAccountHandle targetPhoneAccount,
                                   boolean confirmFirst) {
        try {
            mCallRedirectionAdapter.redirectCall(gatewayUri, targetPhoneAccount, confirmFirst);
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }

    /**
     * The implemented {@link CallRedirectionService} calls this method to response a request
     * received via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)} to inform Telecom that
     * an outgoing call should be canceled entirely.
     *
     * <p>This can only be called from implemented
     * {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}. The response corresponds to the
     * latest request via {@link #onPlaceCall(Uri, PhoneAccountHandle, boolean)}.
     *
     */
    public final void cancelCall() {
        try {
            mCallRedirectionAdapter.cancelCall();
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }

    /**
     * A handler message to process the attempt to place call with redirection service from Telecom
     */
    private static final int MSG_PLACE_CALL = 1;

    /**
     * A handler to process the attempt to place call with redirection service from Telecom
     */
    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_PLACE_CALL:
                    SomeArgs args = (SomeArgs) msg.obj;
                    try {
                        mCallRedirectionAdapter = (ICallRedirectionAdapter) args.arg1;
                        onPlaceCall((Uri) args.arg2, (PhoneAccountHandle) args.arg3,
                                (boolean) args.arg4);
                    } finally {
                        args.recycle();
                    }
                    break;
            }
        }
    };

    private final class CallRedirectionBinder extends ICallRedirectionService.Stub {

        /**
         * Telecom calls this method to inform the CallRedirectionService of a new outgoing call
         * which is about to be placed.
         * @param handle the phone number dialed by the user
         * @param initialPhoneAccount the URI of the number the user dialed
         * @param allowInteractiveResponse a boolean to tell if the implemented
         *                                 {@link CallRedirectionService} should allow interactive
         *                                 responses with users.
         */
        @Override
        public void placeCall(@NonNull ICallRedirectionAdapter adapter, @NonNull Uri handle,
                              @NonNull PhoneAccountHandle initialPhoneAccount,
                              boolean allowInteractiveResponse) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = adapter;
            args.arg2 = handle;
            args.arg3 = initialPhoneAccount;
            args.arg4 = allowInteractiveResponse;
            mHandler.obtainMessage(MSG_PLACE_CALL, args).sendToTarget();
        }
    }

    @Override
    public final @Nullable IBinder onBind(@NonNull Intent intent) {
        return new CallRedirectionBinder();
    }

    @Override
    public final boolean onUnbind(@NonNull Intent intent) {
        return false;
    }
}
