/*
 * Copyright (C) 2014 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.HdmiDeviceInfo;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Buffer storage to keep incoming messages for later processing. Used to
 * handle messages that arrive when the device is not ready. Useful when
 * keeping the messages from a connected device which are not discovered yet.
 */
final class DelayedMessageBuffer {
    private final ArrayList<HdmiCecMessage> mBuffer = new ArrayList<>();
    private final HdmiCecLocalDevice mDevice;

    DelayedMessageBuffer(HdmiCecLocalDevice device) {
        mDevice = device;
    }

    /**
     * Add a new message to the buffer. The buffer keeps selected messages in
     * the order they are received.
     *
     * @param message {@link HdmiCecMessage} to add
     */
    void add(HdmiCecMessage message) {
        boolean buffered = true;

        // Note that all the messages are not handled in the same manner.
        // For &lt;Active Source&gt; we keep the latest one only.
        // TODO: This might not be the best way to choose the active source.
        //       Devise a better way to pick up the best one.
        switch (message.getOpcode()) {
            case Constants.MESSAGE_ACTIVE_SOURCE:
                removeActiveSource();
                mBuffer.add(message);
                break;
            case Constants.MESSAGE_INITIATE_ARC:
            case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
                mBuffer.add(message);
                break;
            default:
                buffered = false;
                break;
        }
        if (buffered) {
            HdmiLogger.debug("Buffering message:" + message);
        }
    }

    private void removeActiveSource() {
        // Uses iterator to remove elements while looping through the list.
        for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
            HdmiCecMessage message = iter.next();
            if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE) {
                iter.remove();
            }
        }
    }

    boolean isBuffered(int opcode) {
        for (HdmiCecMessage message : mBuffer) {
            if (message.getOpcode() == opcode) {
                return true;
            }
        }
        return false;
    }

    void processAllMessages() {
        // Use the copied buffer.
        ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
        mBuffer.clear();
        for (HdmiCecMessage message : copiedBuffer) {
            mDevice.onMessage(message);
            HdmiLogger.debug("Processing message:" + message);
        }
    }

    /**
     * Process messages from a given logical device. Called by
     * {@link NewDeviceAction} actions when they finish adding the device
     * information.
     * <p>&lt;Active Source&gt; is processed only when the TV input is ready.
     * If not, {@link #processActiveSource()} will be invoked later to handle it.
     *
     * @param address logical address of CEC device which the messages to process
     *        are associated with
     */
    void processMessagesForDevice(int address) {
        ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
        mBuffer.clear();
        HdmiLogger.debug("Checking message for address:" + address);
        for (HdmiCecMessage message : copiedBuffer) {
            if (message.getSource() != address) {
                mBuffer.add(message);
                continue;
            }
            if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE
                    && !mDevice.isInputReady(HdmiDeviceInfo.idForCecDevice(address))) {
                mBuffer.add(message);
                continue;
            }
            mDevice.onMessage(message);
            HdmiLogger.debug("Processing message:" + message);
        }
    }

    /**
     * Process &lt;Active Source&gt;.
     *
     * <p>The message has a dependency on TV input framework. Should be invoked
     * after we get the callback
     * {@link android.media.tv.TvInputManager.TvInputCallback#onInputAdded(String)}
     * to ensure the processing of the message takes effect when transformed
     * to input change callback.
     *
     * @param address logical address of the device to be the active source
     */
    void processActiveSource(int address) {
        ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<HdmiCecMessage>(mBuffer);
        mBuffer.clear();
        for (HdmiCecMessage message : copiedBuffer) {
            if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE
                    && message.getSource() == address) {
                mDevice.onMessage(message);
                HdmiLogger.debug("Processing message:" + message);
            } else {
                mBuffer.add(message);
            }
        }
    }
}
