/*
 * 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 com.android.server.hdmi;

import android.hardware.tv.cec.V1_0.SendMessageResult;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Feature action that handles System Audio Mode initiated by AVR devices.
 */
public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction {

    // State that waits for <Active Source> once send <Request Active Source>.
    private static final int STATE_WAITING_FOR_ACTIVE_SOURCE = 1;
    // State that waits for TV supporting Audio System Mode or not
    // once received <Active Source>
    private static final int STATE_WAITING_FOR_TV_SUPPORT = 2;
    @VisibleForTesting
    static final int MAX_RETRY_COUNT = 5;

    private int mSendRequestActiveSourceRetryCount = 0;
    private int mSendSetSystemAudioModeRetryCount = 0;

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

    @Override
    boolean start() {
        if (audioSystem().getActiveSource().physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) {
            mState = STATE_WAITING_FOR_ACTIVE_SOURCE;
            addTimer(mState, HdmiConfig.TIMEOUT_MS);
            sendRequestActiveSource();
        } else {
            queryTvSystemAudioModeSupport();
        }
        return true;
    }

    @Override
    boolean processCommand(HdmiCecMessage cmd) {
        switch (cmd.getOpcode()) {
            case Constants.MESSAGE_ACTIVE_SOURCE:
                // received <Active Source>
                if (mState != STATE_WAITING_FOR_ACTIVE_SOURCE) {
                    return false;
                }
                mActionTimer.clearTimerMessage();
                // Broadcast message is also handled by other device types
                audioSystem().handleActiveSource(cmd);
                mState = STATE_WAITING_FOR_TV_SUPPORT;
                queryTvSystemAudioModeSupport();
                return true;
        }
        return false;
    }

    @Override
    void handleTimerEvent(int state) {
        if (mState != state) {
            return;
        }

        switch (mState) {
            case STATE_WAITING_FOR_ACTIVE_SOURCE:
                handleActiveSourceTimeout();
                break;
        }
    }

    protected void sendRequestActiveSource() {
        sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress()),
                result -> {
                    if (result != SendMessageResult.SUCCESS) {
                        if (mSendRequestActiveSourceRetryCount < MAX_RETRY_COUNT) {
                            mSendRequestActiveSourceRetryCount++;
                            sendRequestActiveSource();
                        } else {
                            audioSystem().checkSupportAndSetSystemAudioMode(false);
                            finish();
                        }
                    }
                });
    }

    protected void sendSetSystemAudioMode(boolean on, int dest) {
        sendCommand(HdmiCecMessageBuilder.buildSetSystemAudioMode(getSourceAddress(),
                dest, on), result -> {
                    if (result != SendMessageResult.SUCCESS) {
                        if (mSendSetSystemAudioModeRetryCount < MAX_RETRY_COUNT) {
                            mSendSetSystemAudioModeRetryCount++;
                            sendSetSystemAudioMode(on, dest);
                        } else {
                            audioSystem().checkSupportAndSetSystemAudioMode(false);
                            finish();
                        }
                    }
                });
    }

    private void handleActiveSourceTimeout() {
        HdmiLogger.debug("Cannot get active source.");
        // If not able to find Active Source and the current device has playbcak functionality,
        // claim Active Source and start to query TV system audio mode support.
        if (audioSystem().mService.isPlaybackDevice()) {
            audioSystem().mService.setAndBroadcastActiveSourceFromOneDeviceType(
                    Constants.ADDR_BROADCAST, getSourcePath());
            mState = STATE_WAITING_FOR_TV_SUPPORT;
            queryTvSystemAudioModeSupport();
        } else {
            audioSystem().checkSupportAndSetSystemAudioMode(false);
        }
        finish();
    }

    private void queryTvSystemAudioModeSupport() {
        audioSystem().queryTvSystemAudioModeSupport(
                supported -> {
                    if (supported) {
                        if (audioSystem().checkSupportAndSetSystemAudioMode(true)) {
                            sendSetSystemAudioMode(true, Constants.ADDR_BROADCAST);
                        }
                        finish();
                    } else {
                        audioSystem().checkSupportAndSetSystemAudioMode(false);
                        finish();
                    }
                });
    }

    private void switchToRelevantInputForDeviceAt(int physicalAddress) {
        // TODO(shubang): implement this method
    }
}
