/*
 * 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 static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_UNKNOWN;

import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.util.SparseIntArray;
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
import java.util.List;

/**
 * Action that check each device's power status.
 */
public class PowerStatusMonitorAction extends HdmiCecFeatureAction {
    private static final String TAG = "PowerStatusMonitorAction";

    // State that waits for <Report Power Status> once sending <Give Device Power Status>
    // to all external devices.
    private static final int STATE_WAIT_FOR_REPORT_POWER_STATUS = 1;
    // State that waits for next monitoring
    private static final int STATE_WAIT_FOR_NEXT_MONITORING = 2;

    private static final int INVALID_POWER_STATUS = POWER_STATUS_UNKNOWN - 1;

    // Monitoring interval (60s)
    private static final int MONITIROING_INTERNAL_MS = 60000;

    // Timeout once sending <Give Device Power Status>
    private static final int REPORT_POWER_STATUS_TIMEOUT_MS = 5000;

    // Container for current power status of all external devices.
    // The key is a logical address a device and the value is current power status of it
    // Whenever the action receives <Report Power Status> from a device,
    // it removes an entry of the given device.
    // If this is non-empty when timeout for STATE_WAIT_FOR_REPORT_POWER_STATUS happens,
    // updates power status of all remaining devices into POWER_STATUS_UNKNOWN.
    private final SparseIntArray mPowerStatus = new SparseIntArray();

    PowerStatusMonitorAction(HdmiCecLocalDevice source) {
        super(source);
    }

    @Override
    boolean start() {
        queryPowerStatus();
        return true;
    }

    @Override
    boolean processCommand(HdmiCecMessage cmd) {
        if (mState == STATE_WAIT_FOR_REPORT_POWER_STATUS
                && cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) {
            return handleReportPowerStatus(cmd);
        }
        return false;
    }

    private boolean handleReportPowerStatus(HdmiCecMessage cmd) {
        int sourceAddress = cmd.getSource();
        int oldStatus = mPowerStatus.get(sourceAddress, INVALID_POWER_STATUS);
        if (oldStatus == INVALID_POWER_STATUS) {
            // if no device exists for incoming message, hands it over to other actions.
            return false;
        }
        int newStatus = cmd.getParams()[0] & 0xFF;
        updatePowerStatus(sourceAddress, newStatus, true);
        return true;
    }

    @Override
    void handleTimerEvent(int state) {
        switch (mState) {
            case STATE_WAIT_FOR_NEXT_MONITORING:
                queryPowerStatus();
                break;
            case STATE_WAIT_FOR_REPORT_POWER_STATUS:
                handleTimeout();
                break;
        }
    }

    private void handleTimeout() {
        for (int i = 0; i < mPowerStatus.size(); ++i) {
            int logicalAddress = mPowerStatus.keyAt(i);
            updatePowerStatus(logicalAddress, POWER_STATUS_UNKNOWN, false);
        }
        mPowerStatus.clear();
        mState = STATE_WAIT_FOR_NEXT_MONITORING;
    }

    private void resetPowerStatus(List<HdmiDeviceInfo> deviceInfos) {
        mPowerStatus.clear();
        for (HdmiDeviceInfo info : deviceInfos) {
            mPowerStatus.append(info.getLogicalAddress(), info.getDevicePowerStatus());
        }
    }

    private void queryPowerStatus() {
        List<HdmiDeviceInfo> deviceInfos = tv().getDeviceInfoList(false);
        resetPowerStatus(deviceInfos);
        for (HdmiDeviceInfo info : deviceInfos) {
            final int logicalAddress = info.getLogicalAddress();
            sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
                    logicalAddress),
                    new SendMessageCallback() {
                        @Override
                        public void onSendCompleted(int error) {
                            // If fails to send <Give Device Power Status>,
                            // update power status into UNKNOWN.
                            if (error != SendMessageResult.SUCCESS) {
                               updatePowerStatus(logicalAddress, POWER_STATUS_UNKNOWN, true);
                            }
                        }
                    });
        }

        mState = STATE_WAIT_FOR_REPORT_POWER_STATUS;

        // Add both timers, monitoring and timeout.
        addTimer(STATE_WAIT_FOR_NEXT_MONITORING, MONITIROING_INTERNAL_MS);
        addTimer(STATE_WAIT_FOR_REPORT_POWER_STATUS, REPORT_POWER_STATUS_TIMEOUT_MS);
    }

    private void updatePowerStatus(int logicalAddress, int newStatus, boolean remove) {
        tv().updateDevicePowerStatus(logicalAddress, newStatus);

        if (remove) {
            mPowerStatus.delete(logicalAddress);
        }
    }
}
