/*
 * 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.hardware.hdmi;

import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.hdmi.HdmiControlManager.ControlCallbackResult;
import android.os.Binder;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * An {@code HdmiSwitchClient} represents a HDMI-CEC switch device.
 *
 * <p>HdmiSwitchClient has a CEC device type of HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH, but it is
 * used by all Android devices that have multiple HDMI inputs, even if it is not a "pure" swicth
 * and has another device type like TV or Player.
 *
 * @hide
 */
@SystemApi
public class HdmiSwitchClient extends HdmiClient {

    private static final String TAG = "HdmiSwitchClient";

    /* package */ HdmiSwitchClient(IHdmiControlService service) {
        super(service);
    }

    private static IHdmiControlCallback getCallbackWrapper(final OnSelectListener listener) {
        return new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
                listener.onSelect(result);
            }
        };
    }

    @Override
    public int getDeviceType() {
        return HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH;
    }

    /**
     * Selects a CEC logical device to be a new active source.
     *
     * @param logicalAddress logical address of the device to select
     * @param listener listener to get the result with
     *
     * @hide
     */
    public void selectDevice(int logicalAddress, @NonNull OnSelectListener listener) {
        Preconditions.checkNotNull(listener);
        try {
            mService.deviceSelect(logicalAddress, getCallbackWrapper(listener));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select device: ", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Selects a HDMI port to be a new route path.
     *
     * @param portId HDMI port to select
     * @see {@link android.media.tv.TvInputHardwareInfo#getHdmiPortId()}
     *     to get portId of a specific TV Input.
     * @param listener listener to get the result with
     *
     * @hide
     */
    @SystemApi
    public void selectPort(int portId, @NonNull OnSelectListener listener) {
        Preconditions.checkNotNull(listener);
        try {
            mService.portSelect(portId, getCallbackWrapper(listener));
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select port: ", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Selects a CEC logical device to be a new active source.
     *
     * @param logicalAddress logical address of the device to select
     * @param executor executor to allow the develper to specify the thread upon which the listeners
     *     will be invoked
     * @param listener listener to get the result with
     *
     * @hide
     */
    public void selectDevice(
            int logicalAddress,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnSelectListener listener) {
        Preconditions.checkNotNull(listener);
        try {
            mService.deviceSelect(logicalAddress,
                    new IHdmiControlCallback.Stub() {
                            @Override
                            public void onComplete(int result) {
                                Binder.withCleanCallingIdentity(
                                        () -> executor.execute(() -> listener.onSelect(result)));
                            }
                    }
            );
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select device: ", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Selects a HDMI port to be a new route path.
     *
     * @param portId HDMI port to select
     * @param executor executor to allow the develper to specify the thread upon which the listeners
     *     will be invoked
     * @param listener listener to get the result with
     *
     * @hide
     */
    @SystemApi
    public void selectPort(
            int portId,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnSelectListener listener) {
        Preconditions.checkNotNull(listener);
        try {
            mService.portSelect(portId,
                    new IHdmiControlCallback.Stub() {
                            @Override
                            public void onComplete(int result) {
                                Binder.withCleanCallingIdentity(
                                        () -> executor.execute(() -> listener.onSelect(result)));
                            }
                    }
            );
        } catch (RemoteException e) {
            Log.e(TAG, "failed to select port: ", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns all the CEC devices connected to the device.
     *
     * <p>This only applies to device with multiple HDMI inputs
     *
     * @return list of {@link HdmiDeviceInfo} for connected CEC devices. Empty list is returned if
     *     there is none.
     *
     * @hide
     */
    public List<HdmiDeviceInfo> getDeviceList() {
        try {
            return mService.getDeviceList();
        } catch (RemoteException e) {
            Log.e("TAG", "Failed to call getDeviceList():", e);
            return Collections.<HdmiDeviceInfo>emptyList();
        }
    }

    /**
     * Listener interface used to get the result of {@link #deviceSelect} or {@link #portSelect}.
     *
     * @hide
     */
    @SystemApi
    public interface OnSelectListener {

        /**
         * Called when the operation is finished.
         *
         * @param result callback result.
         * @see {@link ControlCallbackResult}
         */
        void onSelect(@ControlCallbackResult int result);
    }
}
