/**
 * Copyright (C) 2017 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 android.hardware.radio;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.os.RemoteException;
import android.util.Log;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Implements the RadioTuner interface by forwarding calls to radio service.
 */
class TunerAdapter extends RadioTuner {
    private static final String TAG = "BroadcastRadio.TunerAdapter";

    @NonNull private final ITuner mTuner;
    @NonNull private final TunerCallbackAdapter mCallback;
    private boolean mIsClosed = false;

    private @RadioManager.Band int mBand;

    private ProgramList mLegacyListProxy;
    private Map<String, String> mLegacyListFilter;

    TunerAdapter(@NonNull ITuner tuner, @NonNull TunerCallbackAdapter callback,
            @RadioManager.Band int band) {
        mTuner = Objects.requireNonNull(tuner);
        mCallback = Objects.requireNonNull(callback);
        mBand = band;
    }

    @Override
    public void close() {
        synchronized (mTuner) {
            if (mIsClosed) {
                Log.v(TAG, "Tuner is already closed");
                return;
            }
            mIsClosed = true;
            if (mLegacyListProxy != null) {
                mLegacyListProxy.close();
                mLegacyListProxy = null;
            }
            mCallback.close();
        }
        try {
            mTuner.close();
        } catch (RemoteException e) {
            Log.e(TAG, "Exception trying to close tuner", e);
        }
    }

    @Override
    public int setConfiguration(RadioManager.BandConfig config) {
        if (config == null) return RadioManager.STATUS_BAD_VALUE;
        try {
            mTuner.setConfiguration(config);
            mBand = config.getType();
            return RadioManager.STATUS_OK;
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Can't set configuration", e);
            return RadioManager.STATUS_BAD_VALUE;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
    }

    @Override
    public int getConfiguration(RadioManager.BandConfig[] config) {
        if (config == null || config.length != 1) {
            throw new IllegalArgumentException("The argument must be an array of length 1");
        }
        try {
            config[0] = mTuner.getConfiguration();
            return RadioManager.STATUS_OK;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
    }

    @Override
    public int setMute(boolean mute) {
        try {
            mTuner.setMuted(mute);
        } catch (IllegalStateException e) {
            Log.e(TAG, "Can't set muted", e);
            return RadioManager.STATUS_ERROR;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
        return RadioManager.STATUS_OK;
    }

    @Override
    public boolean getMute() {
        try {
            return mTuner.isMuted();
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return true;
        }
    }

    @Override
    public int step(int direction, boolean skipSubChannel) {
        try {
            mTuner.step(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
        } catch (IllegalStateException e) {
            Log.e(TAG, "Can't step", e);
            return RadioManager.STATUS_INVALID_OPERATION;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
        return RadioManager.STATUS_OK;
    }

    @Override
    public int scan(int direction, boolean skipSubChannel) {
        try {
            mTuner.scan(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
        } catch (IllegalStateException e) {
            Log.e(TAG, "Can't scan", e);
            return RadioManager.STATUS_INVALID_OPERATION;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
        return RadioManager.STATUS_OK;
    }

    @Override
    public int tune(int channel, int subChannel) {
        try {
            mTuner.tune(ProgramSelector.createAmFmSelector(mBand, channel, subChannel));
        } catch (IllegalStateException e) {
            Log.e(TAG, "Can't tune", e);
            return RadioManager.STATUS_INVALID_OPERATION;
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Can't tune", e);
            return RadioManager.STATUS_BAD_VALUE;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
        return RadioManager.STATUS_OK;
    }

    @Override
    public void tune(@NonNull ProgramSelector selector) {
        try {
            mTuner.tune(selector);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public int cancel() {
        try {
            mTuner.cancel();
        } catch (IllegalStateException e) {
            Log.e(TAG, "Can't cancel", e);
            return RadioManager.STATUS_INVALID_OPERATION;
        } catch (RemoteException e) {
            Log.e(TAG, "service died", e);
            return RadioManager.STATUS_DEAD_OBJECT;
        }
        return RadioManager.STATUS_OK;
    }

    @Override
    public void cancelAnnouncement() {
        try {
            mTuner.cancelAnnouncement();
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public int getProgramInformation(RadioManager.ProgramInfo[] info) {
        if (info == null || info.length != 1) {
            Log.e(TAG, "The argument must be an array of length 1");
            return RadioManager.STATUS_BAD_VALUE;
        }

        RadioManager.ProgramInfo current = mCallback.getCurrentProgramInformation();
        if (current == null) {
            Log.w(TAG, "Didn't get program info yet");
            return RadioManager.STATUS_INVALID_OPERATION;
        }
        info[0] = current;
        return RadioManager.STATUS_OK;
    }

    @Override
    public @Nullable Bitmap getMetadataImage(int id) {
        try {
            return mTuner.getImage(id);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public boolean startBackgroundScan() {
        try {
            return mTuner.startBackgroundScan();
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public @NonNull List<RadioManager.ProgramInfo>
            getProgramList(@Nullable Map<String, String> vendorFilter) {
        synchronized (mTuner) {
            if (mLegacyListProxy == null || !Objects.equals(mLegacyListFilter, vendorFilter)) {
                Log.i(TAG, "Program list filter has changed, requesting new list");
                mLegacyListProxy = new ProgramList();
                mLegacyListFilter = vendorFilter;

                mCallback.clearLastCompleteList();
                mCallback.setProgramListObserver(mLegacyListProxy, () -> { });
                try {
                    mTuner.startProgramListUpdates(new ProgramList.Filter(vendorFilter));
                } catch (RemoteException ex) {
                    throw new RuntimeException("service died", ex);
                }
            }

            List<RadioManager.ProgramInfo> list = mCallback.getLastCompleteList();
            if (list == null) throw new IllegalStateException("Program list is not ready yet");
            return list;
        }
    }

    @Override
    public @Nullable ProgramList getDynamicProgramList(@Nullable ProgramList.Filter filter) {
        synchronized (mTuner) {
            if (mLegacyListProxy != null) {
                mLegacyListProxy.close();
                mLegacyListProxy = null;
            }
            mLegacyListFilter = null;

            ProgramList list = new ProgramList();
            mCallback.setProgramListObserver(list, () -> {
                try {
                    mTuner.stopProgramListUpdates();
                } catch (IllegalStateException ex) {
                    // it's fine to not stop updates if tuner is already closed
                } catch (RemoteException ex) {
                    Log.e(TAG, "Couldn't stop program list updates", ex);
                }
            });

            try {
                mTuner.startProgramListUpdates(filter);
            } catch (UnsupportedOperationException ex) {
                Log.i(TAG, "Program list is not supported with this hardware");
                return null;
            } catch (RemoteException ex) {
                mCallback.setProgramListObserver(null, () -> { });
                throw new RuntimeException("service died", ex);
            }

            return list;
        }
    }

    @Override
    public boolean isAnalogForced() {
        try {
            return isConfigFlagSet(RadioManager.CONFIG_FORCE_ANALOG);
        } catch (UnsupportedOperationException ex) {
            throw new IllegalStateException(ex);
        }
    }

    @Override
    public void setAnalogForced(boolean isForced) {
        try {
            setConfigFlag(RadioManager.CONFIG_FORCE_ANALOG, isForced);
        } catch (UnsupportedOperationException ex) {
            throw new IllegalStateException(ex);
        }
    }

    @Override
    public boolean isConfigFlagSupported(@RadioManager.ConfigFlag int flag) {
        try {
            return mTuner.isConfigFlagSupported(flag);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public boolean isConfigFlagSet(@RadioManager.ConfigFlag int flag) {
        try {
            return mTuner.isConfigFlagSet(flag);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public void setConfigFlag(@RadioManager.ConfigFlag int flag, boolean value) {
        try {
            mTuner.setConfigFlag(flag, value);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public @NonNull Map<String, String> setParameters(@NonNull Map<String, String> parameters) {
        try {
            return mTuner.setParameters(Objects.requireNonNull(parameters));
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public @NonNull Map<String, String> getParameters(@NonNull List<String> keys) {
        try {
            return mTuner.getParameters(Objects.requireNonNull(keys));
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public boolean isAntennaConnected() {
        return mCallback.isAntennaConnected();
    }

    @Override
    public boolean hasControl() {
        try {
            // don't rely on mIsClosed, as tuner might get closed internally
            return !mTuner.isClosed();
        } catch (RemoteException e) {
            return false;
        }
    }
}
