/*
 * 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.car.hal;

import android.annotation.Nullable;
import android.car.hardware.radio.CarRadioEvent;
import android.car.hardware.radio.CarRadioPreset;
import android.hardware.radio.RadioManager;
import android.hardware.vehicle.V2_0.VehiclePropConfig;
import android.hardware.vehicle.V2_0.VehiclePropValue;
import android.hardware.vehicle.V2_0.VehicleProperty;
import android.hardware.vehicle.V2_0.VehicleRadioConstants;
import android.util.Log;

import com.android.car.CarLog;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * This class exposes the Radio related features in the HAL layer.
 *
 * The current set of features support radio presets. The rest of the radio functionality is already
 * covered under RadioManager API.
 */
public class RadioHalService extends HalServiceBase {
    public static boolean DBG = false;
    public static String TAG = CarLog.TAG_HAL + ".RadioHalService";

    private int mPresetCount = 0;
    private VehicleHal mHal;
    private RadioListener mListener;

    public interface RadioListener {
        void onEvent(CarRadioEvent event);
    }

    public RadioHalService(VehicleHal hal) {
        mHal = hal;
    }

    @Override
    public synchronized void init() {
    }

    @Override
    public synchronized void release() {
        mListener = null;
    }

    @Override
    public synchronized Collection<VehiclePropConfig> takeSupportedProperties(
            Collection<VehiclePropConfig> allProperties) {
        Collection<VehiclePropConfig> supported = new LinkedList<>();
        for (VehiclePropConfig p : allProperties) {
            if (handleRadioProperty(p)) {
                supported.add(p);
            }
        }
        return supported;
    }

    @Override
    public void handleHalEvents(List<VehiclePropValue> values) {
        if (DBG) {
            Log.d(TAG, "handleHalEvents");
        }
        RadioHalService.RadioListener radioListener;
        synchronized (this) {
            radioListener = mListener;
        }

        if (radioListener == null) {
            Log.e(TAG, "radio listener is null, ignoring event: " + values);
            return;
        }

        for (VehiclePropValue v : values) {
            CarRadioEvent radioEvent = createCarRadioEvent(v);
            if (radioEvent != null) {
                if (DBG) {
                    Log.d(TAG, "Sending event to listener: " + radioEvent);
                }
                radioListener.onEvent(radioEvent);
            } else {
                Log.w(TAG, "Value conversion failed: " + v);
            }
        }
    }

    @Override
    public void dump(PrintWriter writer) {
        writer.println("*RadioHal*");
        writer.println("**Supported properties**");
        writer.println(VehicleProperty.RADIO_PRESET);
        if (mListener != null) {
            writer.println("Hal service registered.");
        }
    }

    public synchronized void registerListener(RadioListener listener) {
        if (DBG) {
            Log.d(TAG, "registerListener");
        }
        mListener = listener;

        // Subscribe to all radio properties.
        mHal.subscribeProperty(this, VehicleProperty.RADIO_PRESET, 0);
    }

    public synchronized void unregisterListener() {
        if (DBG) {
            Log.d(TAG, "unregisterListener");
        }
        mListener = null;

        // Unsubscribe from all properties.
        mHal.unsubscribeProperty(this, VehicleProperty.RADIO_PRESET);
    }

    public synchronized int getPresetCount() {
        Log.d(TAG, "get preset count: " + mPresetCount);
        return mPresetCount;
    }

    @Nullable
    public CarRadioPreset getRadioPreset(int presetNumber) {
        // Check if the preset number is out of range. We should return NULL if that is the case.
        if (DBG) {
            Log.d(TAG, "getRadioPreset called with preset number " + presetNumber);
        }
        if (!isValidPresetNumber(presetNumber)) {
            throw new IllegalArgumentException("Preset number not valid: " + presetNumber);
        }

        VehiclePropValue presetNumberValue = new VehiclePropValue();
        presetNumberValue.prop = VehicleProperty.RADIO_PRESET;
        presetNumberValue.value.int32Values.addAll(Arrays.asList(presetNumber, 0, 0, 0));

        VehiclePropValue presetConfig;
        try {
            presetConfig = mHal.get(presetNumberValue);
        } catch (PropertyTimeoutException e) {
            Log.e(TAG, "property VehicleProperty.RADIO_PRESET not ready", e);
            return null;
        }
        // Sanity check the output from HAL.
        if (presetConfig.value.int32Values.size() != 4) {
            Log.e(TAG, "Return value does not have 4 elements: " +
                Arrays.toString(presetConfig.value.int32Values.toArray()));
            throw new IllegalStateException(
                "Invalid preset returned from service: "
                        + Arrays.toString(presetConfig.value.int32Values.toArray()));
        }

        int retPresetNumber = presetConfig.value.int32Values.get(0);
        int retBand = presetConfig.value.int32Values.get(1);
        int retChannel = presetConfig.value.int32Values.get(2);
        int retSubChannel = presetConfig.value.int32Values.get(3);
        if (retPresetNumber != presetNumber) {
            Log.e(TAG, "Preset number is not the same: " + presetNumber + " vs " + retPresetNumber);
            return null;
        }
        if (!isValidBand(retBand)) return null;

        // Return the actual config.
        CarRadioPreset retConfig =
            new CarRadioPreset(retPresetNumber, retBand, retChannel, retSubChannel);
        if (DBG) {
            Log.d(TAG, "Preset obtained: " + retConfig);
        }
        return retConfig;
    }

    public boolean setRadioPreset(CarRadioPreset preset) {
        if (DBG) {
            Log.d(TAG, "setRadioPreset with config " + preset);
        }

        if (!isValidPresetNumber(preset.getPresetNumber()) ||
            !isValidBand(preset.getBand())) {
            return false;
        }

        try {
            mHal.set(VehicleProperty.RADIO_PRESET).to(new int[] {
                    preset.getPresetNumber(),
                    preset.getBand(),
                    preset.getChannel(),
                    preset.getSubChannel()});
        } catch (PropertyTimeoutException e) {
            Log.e(CarLog.TAG_POWER, "cannot set to RADIO_PRESET", e);
            return false;
        }
        return true;
    }

    private boolean isValidPresetNumber(int presetNumber) {
        // Check for preset number.
        if (presetNumber < VehicleRadioConstants.VEHICLE_RADIO_PRESET_MIN_VALUE
            || presetNumber > mPresetCount) {
            Log.e(TAG, "Preset number not in range (1, " + mPresetCount + ") - " + presetNumber);
            return false;
        }
        return true;
    }

    private boolean isValidBand(int band) {
        // Check for band info.
        if (band != RadioManager.BAND_AM &&
            band != RadioManager.BAND_FM &&
            band != RadioManager.BAND_FM_HD &&
            band != RadioManager.BAND_AM_HD) {
            Log.e(TAG, "Preset band is not valid: " + band);
            return false;
        }
        return true;
    }

    private boolean handleRadioProperty(VehiclePropConfig property) {
        switch (property.prop) {
            case VehicleProperty.RADIO_PRESET:
                // Extract the count of presets.
                mPresetCount = property.configArray.get(0);
                Log.d(TAG, "Read presets count: " + mPresetCount);
                return true;
            default:
                return false;
        }
        // Should never come here.
    }

    private CarRadioEvent createCarRadioEvent(VehiclePropValue v) {
        switch (v.prop) {
            case VehicleProperty.RADIO_PRESET:
                int vecSize = v.value.int32Values.size();
                if (vecSize != 4) {
                    Log.e(TAG, "Returned a wrong array size: " + vecSize);
                    return null;
                }

                Integer intValues[] = new Integer[4];
                v.value.int32Values.toArray(intValues);

                // Verify the correctness of the values.
                if (!isValidPresetNumber(intValues[0]) && !isValidBand(intValues[1])) {
                    return null;
                }

                CarRadioPreset preset =
                    new CarRadioPreset(intValues[0], intValues[1], intValues[2], intValues[3]);
                CarRadioEvent event = new CarRadioEvent(CarRadioEvent.RADIO_PRESET, preset);
                return event;
            default:
                Log.e(TAG, "createCarRadioEvent: Value not supported as event: " + v);
                return null;
        }
    }
}
