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

import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.net.Uri;
import android.os.Handler;
import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.util.ArraySet;
import android.util.Log;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.ChannelDataManager;
import com.android.tv.data.api.Channel;
import com.android.tv.util.TvInputManagerHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * It manages the current tuned channel among browsable channels. And it determines the next channel
 * by channel up/down. But, it doesn't actually tune through TvView.
 */
@MainThread
public class ChannelTuner {
    private static final String TAG = "ChannelTuner";

    private boolean mStarted;
    private boolean mChannelDataManagerLoaded;
    private final List<Channel> mChannels = new ArrayList<>();
    private final List<Channel> mBrowsableChannels = new ArrayList<>();
    private final Map<Long, Channel> mChannelMap = new HashMap<>();
    // TODO: need to check that mChannelIndexMap can be removed, once mCurrentChannelIndex
    // is changed to mCurrentChannel(Id).
    private final Map<Long, Integer> mChannelIndexMap = new HashMap<>();

    private final Handler mHandler = new Handler();
    private final ChannelDataManager mChannelDataManager;
    private final Set<Listener> mListeners = new ArraySet<>();
    @Nullable private Channel mCurrentChannel;
    private final TvInputManagerHelper mInputManager;
    @Nullable private TvInputInfo mCurrentChannelInputInfo;

    private final ChannelDataManager.Listener mChannelDataManagerListener =
            new ChannelDataManager.Listener() {
                @Override
                public void onLoadFinished() {
                    mChannelDataManagerLoaded = true;
                    updateChannelData(mChannelDataManager.getChannelList());
                    for (Listener l : mListeners) {
                        l.onLoadFinished();
                    }
                }

                @Override
                public void onChannelListUpdated() {
                    updateChannelData(mChannelDataManager.getChannelList());
                }

                @Override
                public void onChannelBrowsableChanged() {
                    updateBrowsableChannels();
                    for (Listener l : mListeners) {
                        l.onBrowsableChannelListChanged();
                    }
                }
            };

    public ChannelTuner(ChannelDataManager channelDataManager, TvInputManagerHelper inputManager) {
        mChannelDataManager = channelDataManager;
        mInputManager = inputManager;
    }

    /** Starts ChannelTuner. It cannot be called twice before calling {@link #stop}. */
    public void start() {
        if (mStarted) {
            throw new IllegalStateException("start is called twice");
        }
        mStarted = true;
        mChannelDataManager.addListener(mChannelDataManagerListener);
        if (mChannelDataManager.isDbLoadFinished()) {
            mHandler.post(mChannelDataManagerListener::onLoadFinished);
        }
    }

    /** Stops ChannelTuner. */
    public void stop() {
        if (!mStarted) {
            return;
        }
        mStarted = false;
        mHandler.removeCallbacksAndMessages(null);
        mChannelDataManager.removeListener(mChannelDataManagerListener);
        mCurrentChannel = null;
        mChannels.clear();
        mBrowsableChannels.clear();
        mChannelMap.clear();
        mChannelIndexMap.clear();
        mChannelDataManagerLoaded = false;
    }

    /** Returns true, if all the channels are loaded. */
    public boolean areAllChannelsLoaded() {
        return mChannelDataManagerLoaded;
    }

    /** Returns browsable channel lists. */
    public List<Channel> getBrowsableChannelList() {
        return Collections.unmodifiableList(mBrowsableChannels);
    }

    /** Returns the number of browsable channels. */
    public int getBrowsableChannelCount() {
        return mBrowsableChannels.size();
    }

    /** Returns the current channel. */
    @Nullable
    public Channel getCurrentChannel() {
        return mCurrentChannel;
    }

    /**
     * Sets the current channel. Call this method only when setting the current channel without
     * actually tuning to it.
     *
     * @param currentChannel The new current channel to set to.
     */
    public void setCurrentChannel(Channel currentChannel) {
        mCurrentChannel = currentChannel;
    }

    /** Returns the current channel's ID. */
    public long getCurrentChannelId() {
        return mCurrentChannel != null ? mCurrentChannel.getId() : Channel.INVALID_ID;
    }

    /** Returns the current channel's URI */
    public Uri getCurrentChannelUri() {
        if (mCurrentChannel == null) {
            return null;
        }
        if (mCurrentChannel.isPassthrough()) {
            return TvContract.buildChannelUriForPassthroughInput(mCurrentChannel.getInputId());
        } else {
            return TvContract.buildChannelUri(mCurrentChannel.getId());
        }
    }

    /** Returns the current {@link TvInputInfo}. */
    @Nullable
    public TvInputInfo getCurrentInputInfo() {
        return mCurrentChannelInputInfo;
    }

    /** Returns true, if the current channel is for a passthrough TV input. */
    public boolean isCurrentChannelPassthrough() {
        return mCurrentChannel != null && mCurrentChannel.isPassthrough();
    }

    /**
     * Moves the current channel to the next (or previous) browsable channel.
     *
     * @return true, if the channel is changed to the adjacent channel. If there is no browsable
     *     channel, it returns false.
     */
    public boolean moveToAdjacentBrowsableChannel(boolean up) {
        Channel channel = getAdjacentBrowsableChannel(up);
        if (channel == null) {
            return false;
        }
        setCurrentChannelAndNotify(mChannelMap.get(channel.getId()));
        return true;
    }

    /**
     * Returns a next browsable channel. It doesn't change the current channel unlike {@link
     * #moveToAdjacentBrowsableChannel}.
     */
    public Channel getAdjacentBrowsableChannel(boolean up) {
        if (isCurrentChannelPassthrough() || getBrowsableChannelCount() == 0) {
            return null;
        }
        int channelIndex;
        if (mCurrentChannel == null) {
            channelIndex = 0;
            Channel channel = mChannels.get(channelIndex);
            if (channel.isBrowsable()) {
                return channel;
            }
        } else {
            channelIndex = mChannelIndexMap.get(mCurrentChannel.getId());
        }
        int size = mChannels.size();
        for (int i = 0; i < size; ++i) {
            int nextChannelIndex = up ? channelIndex + 1 + i : channelIndex - 1 - i + size;
            if (nextChannelIndex >= size) {
                nextChannelIndex -= size;
            }
            Channel channel = mChannels.get(nextChannelIndex);
            if (channel.isBrowsable()) {
                return channel;
            }
        }
        Log.e(TAG, "This code should not be reached");
        return null;
    }

    /**
     * Finds the nearest browsable channel from a channel with {@code channelId}. If the channel
     * with {@code channelId} is browsable, the channel will be returned.
     */
    public Channel findNearestBrowsableChannel(long channelId) {
        if (getBrowsableChannelCount() == 0) {
            return null;
        }
        Channel channel = mChannelMap.get(channelId);
        if (channel == null) {
            return mBrowsableChannels.get(0);
        } else if (channel.isBrowsable()) {
            return channel;
        }
        int index = mChannelIndexMap.get(channelId);
        int size = mChannels.size();
        for (int i = 1; i <= size / 2; ++i) {
            Channel upChannel = mChannels.get((index + i) % size);
            if (upChannel.isBrowsable()) {
                return upChannel;
            }
            Channel downChannel = mChannels.get((index - i + size) % size);
            if (downChannel.isBrowsable()) {
                return downChannel;
            }
        }
        throw new IllegalStateException(
                "This code should be unreachable in findNearestBrowsableChannel");
    }

    /**
     * Moves the current channel to {@code channel}. It can move to a non-browsable channel as well
     * as a browsable channel.
     *
     * @return true, the channel change is success. But, if the channel doesn't exist, the channel
     *     change will be failed and it will return false.
     */
    public boolean moveToChannel(Channel channel) {
        if (channel == null) {
            return false;
        }
        if (channel.isPassthrough()) {
            setCurrentChannelAndNotify(channel);
            return true;
        }
        SoftPreconditions.checkState(mChannelDataManagerLoaded, TAG, "Channel data is not loaded");
        Channel newChannel = mChannelMap.get(channel.getId());
        if (newChannel != null) {
            setCurrentChannelAndNotify(newChannel);
            return true;
        }
        return false;
    }

    /** Resets the current channel to {@code null}. */
    public void resetCurrentChannel() {
        setCurrentChannelAndNotify(null);
    }

    /** Adds {@link Listener}. */
    public void addListener(Listener listener) {
        mListeners.add(listener);
    }

    /** Removes {@link Listener}. */
    public void removeListener(Listener listener) {
        mListeners.remove(listener);
    }

    public interface Listener {
        /** Called when all the channels are loaded. */
        void onLoadFinished();
        /** Called when the browsable channel list is changed. */
        void onBrowsableChannelListChanged();
        /** Called when the current channel is removed. */
        void onCurrentChannelUnavailable(Channel channel);
        /** Called when the current channel is changed. */
        void onChannelChanged(Channel previousChannel, Channel currentChannel);
    }

    private void setCurrentChannelAndNotify(Channel channel) {
        if (mCurrentChannel == channel
                || (channel != null && channel.hasSameReadOnlyInfo(mCurrentChannel))) {
            return;
        }
        Channel previousChannel = mCurrentChannel;
        mCurrentChannel = channel;
        if (mCurrentChannel != null) {
            mCurrentChannelInputInfo = mInputManager.getTvInputInfo(mCurrentChannel.getInputId());
        }
        for (Listener l : mListeners) {
            l.onChannelChanged(previousChannel, mCurrentChannel);
        }
    }

    private void updateChannelData(List<Channel> channels) {
        mChannels.clear();
        mChannels.addAll(channels);

        mChannelMap.clear();
        mChannelIndexMap.clear();
        for (int i = 0; i < channels.size(); ++i) {
            Channel channel = channels.get(i);
            long channelId = channel.getId();
            mChannelMap.put(channelId, channel);
            mChannelIndexMap.put(channelId, i);
        }
        updateBrowsableChannels();

        if (mCurrentChannel != null && !mCurrentChannel.isPassthrough()) {
            Channel prevChannel = mCurrentChannel;
            setCurrentChannelAndNotify(mChannelMap.get(mCurrentChannel.getId()));
            if (mCurrentChannel == null) {
                for (Listener l : mListeners) {
                    l.onCurrentChannelUnavailable(prevChannel);
                }
            }
        }
        // TODO: Do not call onBrowsableChannelListChanged, when only non-browsable
        // channels are changed.
        for (Listener l : mListeners) {
            l.onBrowsableChannelListChanged();
        }
    }

    private void updateBrowsableChannels() {
        mBrowsableChannels.clear();
        for (Channel channel : mChannels) {
            if (channel.isBrowsable()) {
                mBrowsableChannels.add(channel);
            }
        }
    }
}
