/*
**
** Copyright 2016, 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.commands.media;

import android.content.Context;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IAudioService;
import android.os.ServiceManager;
import android.util.AndroidException;

import com.android.internal.os.BaseCommand;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.ArrayIndexOutOfBoundsException;

/**
 * Command line tool to exercise AudioService.setStreamVolume()
 *                           and AudioService.adjustStreamVolume()
 */
public class VolumeCtrl {

    private final static String TAG = "VolumeCtrl";

    // --stream affects --set, --adj or --get options.
    // --show affects --set and --adj options.
    // --get can be used with --set, --adj or by itself.
    public final static String USAGE = new String(
            "the options are as follows: \n" +
            "\t\t--stream STREAM selects the stream to control, see AudioManager.STREAM_*\n" +
            "\t\t                controls AudioManager.STREAM_MUSIC if no stream is specified\n"+
            "\t\t--set INDEX     sets the volume index value\n" +
            "\t\t--adj DIRECTION adjusts the volume, use raise|same|lower for the direction\n" +
            "\t\t--get           outputs the current volume\n" +
            "\t\t--show          shows the UI during the volume change\n" +
            "\texamples:\n" +
            "\t\tadb shell media volume --show --stream 3 --set 11\n" +
            "\t\tadb shell media volume --stream 0 --adj lower\n" +
            "\t\tadb shell media volume --stream 3 --get\n"
            );

    private final static int VOLUME_CONTROL_MODE_SET = 1;
    private final static int VOLUME_CONTROL_MODE_ADJUST = 2;

    private final static String ADJUST_LOWER = "lower";
    private final static String ADJUST_SAME = "same";
    private final static String ADJUST_RAISE = "raise";

    public static void run(BaseCommand cmd) throws Exception {
        //----------------------------------------
        // Default parameters
        int stream = AudioManager.STREAM_MUSIC;
        int volIndex = 5;
        int mode = 0;
        int adjDir = AudioManager.ADJUST_RAISE;
        boolean showUi = false;
        boolean doGet = false;

        //----------------------------------------
        // read options
        String option;
        String adjustment = null;
        while ((option = cmd.nextOption()) != null) {
            switch (option) {
                case "--show":
                    showUi = true;
                    break;
                case "--get":
                    doGet = true;
                    log(LOG_V, "will get volume");
                    break;
                case "--stream":
                    stream = Integer.decode(cmd.nextArgRequired()).intValue();
                    log(LOG_V, "will control stream=" + stream + " (" + streamName(stream) + ")");
                    break;
                case "--set":
                    volIndex = Integer.decode(cmd.nextArgRequired()).intValue();
                    mode = VOLUME_CONTROL_MODE_SET;
                    log(LOG_V, "will set volume to index=" + volIndex);
                    break;
                case "--adj":
                    mode = VOLUME_CONTROL_MODE_ADJUST;
                    adjustment = cmd.nextArgRequired();
                    log(LOG_V, "will adjust volume");
                    break;
                default:
                    throw new IllegalArgumentException("Unknown argument " + option);
            }
        }

        //------------------------------
        // Read options: validation
        if (mode == VOLUME_CONTROL_MODE_ADJUST) {
            if (adjustment == null) {
                cmd.showError("Error: no valid volume adjustment (null)");
                return;
            }
            switch (adjustment) {
                case ADJUST_RAISE: adjDir = AudioManager.ADJUST_RAISE; break;
                case ADJUST_SAME: adjDir = AudioManager.ADJUST_SAME; break;
                case ADJUST_LOWER: adjDir = AudioManager.ADJUST_LOWER; break;
                default:
                    cmd.showError("Error: no valid volume adjustment, was " + adjustment
                            + ", expected " + ADJUST_LOWER + "|" + ADJUST_SAME + "|"
                            + ADJUST_RAISE);
                    return;
            }
        }

        //----------------------------------------
        // Test initialization
        log(LOG_V, "Connecting to AudioService");
        IAudioService audioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
                Context.AUDIO_SERVICE));
        if (audioService == null) {
            System.err.println(BaseCommand.NO_SYSTEM_ERROR_CODE);
            throw new AndroidException(
                    "Can't connect to audio service; is the system running?");
        }

        if (mode == VOLUME_CONTROL_MODE_SET) {
            if ((volIndex > audioService.getStreamMaxVolume(stream))
                    || (volIndex < audioService.getStreamMinVolume(stream))) {
                cmd.showError(String.format("Error: invalid volume index %d for stream %d "
                        + "(should be in [%d..%d])", volIndex, stream,
                        audioService.getStreamMinVolume(stream),
                        audioService.getStreamMaxVolume(stream)));
                return;
            }
        }

        //----------------------------------------
        // Non-interactive test
        final int flag = showUi? AudioManager.FLAG_SHOW_UI : 0;
        final String pack = cmd.getClass().getPackage().getName();
        if (mode == VOLUME_CONTROL_MODE_SET) {
            audioService.setStreamVolume(stream, volIndex, flag, pack/*callingPackage*/);
        } else if (mode == VOLUME_CONTROL_MODE_ADJUST) {
            audioService.adjustStreamVolume(stream, adjDir, flag, pack);
        }
        if (doGet) {
            log(LOG_V, "volume is " + audioService.getStreamVolume(stream) +
                       " in range [" + audioService.getStreamMinVolume(stream) +
                       ".." + audioService.getStreamMaxVolume(stream) + "]");
        }
    }

    //--------------------------------------------
    // Utilities

    static final String LOG_V = "[v]";
    static final String LOG_W = "[w]";
    static final String LOG_OK = "[ok]";

    static void log(String code, String msg) {
        System.out.println(code + " " + msg);
    }

    static String streamName(int stream) {
        try {
            return AudioSystem.STREAM_NAMES[stream];
        } catch (ArrayIndexOutOfBoundsException e) {
            return "invalid stream";
        }
    }

}
