/*
 * Copyright (C) 2015 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.server.hdmi;

import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlCallback;
import android.os.RemoteException;
import android.util.Slog;

/**
 * Buffer for portSelect/deviceSelect requests. Requests made before the address allocation
 * are stored in this buffer, and processed when the allocation is completed.
 *
 * <p>This is put into action only if we are a TV device.
 */
public class SelectRequestBuffer {
    private static final String TAG = "SelectRequestBuffer";

    public static final SelectRequestBuffer EMPTY_BUFFER = new SelectRequestBuffer() {
        @Override
        public void process() {
            // Do nothing.
        }
    };

    /**
     * Parent class from which buffer for select requests are inherited. Keeps the callback
     * and the device/port ID.
     */
    public static abstract class SelectRequest {
        protected final HdmiControlService mService;
        protected final IHdmiControlCallback mCallback;
        protected final int mId;

        public SelectRequest(HdmiControlService service, int id, IHdmiControlCallback callback) {
            mService = service;
            mId = id;
            mCallback = callback;
        }

        protected HdmiCecLocalDeviceTv tv() {
            return mService.tv();
        }

        protected boolean isLocalDeviceReady() {
            if (tv() == null) {
                Slog.e(TAG, "Local tv device not available");
                invokeCallback(HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE);
                return false;
            }
            return true;
        }

        private void invokeCallback(int reason) {
            try {
                if (mCallback != null) {
                    mCallback.onComplete(reason);
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "Invoking callback failed:" + e);
            }
        }

        /**
         * Implement this method with a customize action to perform when the request gets
         * invoked in a deferred manner.
         */
        public abstract void process();
    }

    public static class DeviceSelectRequest extends SelectRequest {
        private DeviceSelectRequest(HdmiControlService srv, int id, IHdmiControlCallback callback) {
            super(srv, id, callback);
        }

        @Override
        public void process() {
            if (isLocalDeviceReady()) {
                Slog.v(TAG, "calling delayed deviceSelect id:" + mId);
                tv().deviceSelect(mId, mCallback);
            }
        }
    }

    public static class PortSelectRequest extends SelectRequest {
        private PortSelectRequest(HdmiControlService srv, int id, IHdmiControlCallback callback) {
            super(srv, id, callback);
        }

        @Override
        public void process() {
            if (isLocalDeviceReady()) {
                Slog.v(TAG, "calling delayed portSelect id:" + mId);
                tv().doManualPortSwitching(mId, mCallback);
            }
        }
    }

    public static DeviceSelectRequest newDeviceSelect(HdmiControlService srv, int id,
            IHdmiControlCallback callback) {
        return new DeviceSelectRequest(srv, id, callback);
    }

    public static PortSelectRequest newPortSelect(HdmiControlService srv, int id,
            IHdmiControlCallback callback) {
        return new PortSelectRequest(srv, id, callback);
    }

    // The last select request made by system/app. Note that we do not manage a list of requests
    // but just keep only the last one since it already invalidates the older ones.
    private SelectRequest mRequest;

    public void set(SelectRequest request) {
        mRequest = request;
    }

    public void process() {
        if (mRequest != null) {
            mRequest.process();
            clear();
        }
    }

    public void clear() {
        mRequest = null;
    }
}
