/*
 * Copyright (C) 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.tv.dvr.ui.list;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Log;

import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.ScheduledRecording;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.DateHeaderRow;
import com.android.tv.util.Utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * An adapter for {@link ScheduleRow}.
 */
public class ScheduleRowAdapter extends ArrayObjectAdapter {
    private static final String TAG = "ScheduleRowAdapter";
    private static final boolean DEBUG = false;

    private final static long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);

    private static final int MSG_UPDATE_ROW = 1;

    private Context mContext;
    private final List<String> mTitles = new ArrayList<>();
    private final Set<ScheduleRow> mPendingUpdate = new ArraySet<>();

    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_UPDATE_ROW) {
                long currentTimeMs = System.currentTimeMillis();
                handleUpdateRow(currentTimeMs);
                sendNextUpdateMessage(currentTimeMs);
            }
        }
    };

    public ScheduleRowAdapter(Context context, ClassPresenterSelector classPresenterSelector) {
        super(classPresenterSelector);
        mContext = context;
        mTitles.add(mContext.getString(R.string.dvr_date_today));
        mTitles.add(mContext.getString(R.string.dvr_date_tomorrow));
    }

    /**
     * Returns context.
     */
    protected Context getContext() {
        return mContext;
    }

    /**
     * Starts schedule row adapter.
     */
    public void start() {
        clear();
        List<ScheduledRecording> recordingList = TvApplication.getSingletons(mContext)
                .getDvrDataManager().getNonStartedScheduledRecordings();
        recordingList.addAll(TvApplication.getSingletons(mContext).getDvrDataManager()
                .getStartedRecordings());
        Collections.sort(recordingList,
                ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR);
        long deadLine = Utils.getLastMillisecondOfDay(System.currentTimeMillis());
        for (int i = 0; i < recordingList.size();) {
            ArrayList<ScheduledRecording> section = new ArrayList<>();
            while (i < recordingList.size() && recordingList.get(i).getStartTimeMs() < deadLine) {
                section.add(recordingList.get(i++));
            }
            if (!section.isEmpty()) {
                SchedulesHeaderRow headerRow = new DateHeaderRow(calculateHeaderDate(deadLine),
                        mContext.getResources().getQuantityString(
                        R.plurals.dvr_schedules_section_subtitle, section.size(), section.size()),
                        section.size(), deadLine);
                add(headerRow);
                for(ScheduledRecording recording : section){
                    add(new ScheduleRow(recording, headerRow));
                }
            }
            deadLine += ONE_DAY_MS;
        }
        sendNextUpdateMessage(System.currentTimeMillis());
    }

    private String calculateHeaderDate(long deadLine) {
        int titleIndex = (int) ((deadLine -
                Utils.getLastMillisecondOfDay(System.currentTimeMillis())) / ONE_DAY_MS);
        String headerDate;
        if (titleIndex < mTitles.size()) {
            headerDate = mTitles.get(titleIndex);
        } else {
            headerDate = DateUtils.formatDateTime(getContext(), deadLine,
                    DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE
                            | DateUtils.FORMAT_ABBREV_MONTH);
        }
        return headerDate;
    }

    /**
     * Stops schedules row adapter.
     */
    public void stop() {
        mHandler.removeCallbacksAndMessages(null);
        DvrManager dvrManager = TvApplication.getSingletons(getContext()).getDvrManager();
        for (int i = 0; i < size(); i++) {
            if (get(i) instanceof ScheduleRow) {
                ScheduleRow row = (ScheduleRow) get(i);
                if (row.isScheduleCanceled()) {
                    dvrManager.removeScheduledRecording(row.getSchedule());
                }
            }
        }
    }

    /**
     * Gets which {@link ScheduleRow} the {@link ScheduledRecording} belongs to.
     */
    public ScheduleRow findRowByScheduledRecording(ScheduledRecording recording) {
        if (recording == null) {
            return null;
        }
        for (int i = 0; i < size(); i++) {
            Object item = get(i);
            if (item instanceof ScheduleRow && ((ScheduleRow) item).getSchedule() != null) {
                if (((ScheduleRow) item).getSchedule().getId() == recording.getId()) {
                    return (ScheduleRow) item;
                }
            }
        }
        return null;
    }

    private ScheduleRow findRowWithStartRequest(ScheduledRecording schedule) {
        for (int i = 0; i < size(); i++) {
            Object item = get(i);
            if (!(item instanceof ScheduleRow)) {
                continue;
            }
            ScheduleRow row = (ScheduleRow) item;
            if (row.getSchedule() != null && row.isStartRecordingRequested()
                    && row.matchSchedule(schedule)) {
                return row;
            }
        }
        return null;
    }

    private void addScheduleRow(ScheduledRecording recording) {
        // This method must not be called from inherited class.
        SoftPreconditions.checkState(getClass().equals(ScheduleRowAdapter.class));
        if (recording != null) {
            int pre = -1;
            int index = 0;
            for (; index < size(); index++) {
                if (get(index) instanceof ScheduleRow) {
                    ScheduleRow scheduleRow = (ScheduleRow) get(index);
                    if (ScheduledRecording.START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR.compare(
                            scheduleRow.getSchedule(), recording) > 0) {
                        break;
                    }
                    pre = index;
                }
            }
            long deadLine = Utils.getLastMillisecondOfDay(recording.getStartTimeMs());
            if (pre >= 0 && getHeaderRow(pre).getDeadLineMs() == deadLine) {
                SchedulesHeaderRow headerRow = ((ScheduleRow) get(pre)).getHeaderRow();
                headerRow.setItemCount(headerRow.getItemCount() + 1);
                ScheduleRow addedRow = new ScheduleRow(recording, headerRow);
                add(++pre, addedRow);
                updateHeaderDescription(headerRow);
            } else if (index < size() && getHeaderRow(index).getDeadLineMs() == deadLine) {
                SchedulesHeaderRow headerRow = ((ScheduleRow) get(index)).getHeaderRow();
                headerRow.setItemCount(headerRow.getItemCount() + 1);
                ScheduleRow addedRow = new ScheduleRow(recording, headerRow);
                add(index, addedRow);
                updateHeaderDescription(headerRow);
            } else {
                SchedulesHeaderRow headerRow = new DateHeaderRow(calculateHeaderDate(deadLine),
                        mContext.getResources().getQuantityString(
                        R.plurals.dvr_schedules_section_subtitle, 1, 1), 1, deadLine);
                add(++pre, headerRow);
                ScheduleRow addedRow = new ScheduleRow(recording, headerRow);
                add(pre, addedRow);
            }
        }
    }

    private DateHeaderRow getHeaderRow(int index) {
        return ((DateHeaderRow) ((ScheduleRow) get(index)).getHeaderRow());
    }

    private void removeScheduleRow(ScheduleRow scheduleRow) {
        // This method must not be called from inherited class.
        SoftPreconditions.checkState(getClass().equals(ScheduleRowAdapter.class));
        if (scheduleRow != null) {
            scheduleRow.setSchedule(null);
            SchedulesHeaderRow headerRow = scheduleRow.getHeaderRow();
            remove(scheduleRow);
            // Changes the count information of header which the removed row belongs to.
            if (headerRow != null) {
                int currentCount = headerRow.getItemCount();
                headerRow.setItemCount(--currentCount);
                if (headerRow.getItemCount() == 0) {
                    remove(headerRow);
                } else {
                    replace(indexOf(headerRow), headerRow);
                    updateHeaderDescription(headerRow);
                }
            }
        }
    }

    private void updateHeaderDescription(SchedulesHeaderRow headerRow) {
        headerRow.setDescription(mContext.getResources().getQuantityString(
                R.plurals.dvr_schedules_section_subtitle,
                headerRow.getItemCount(), headerRow.getItemCount()));
    }

    /**
     * Called when a schedule recording is added to dvr date manager.
     */
    public void onScheduledRecordingAdded(ScheduledRecording schedule) {
        if (DEBUG) Log.d(TAG, "onScheduledRecordingAdded: " + schedule);
        ScheduleRow row = findRowWithStartRequest(schedule);
        // If the start recording is requested, onScheduledRecordingAdded is called with NOT_STARTED
        // state. And then onScheduleRecordingUpdated will be called with IN_PROGRESS.
        // It happens in a short time and causes blinking. To avoid this intermediate state change,
        // update the row in onScheduleRecordingUpdated when the state changes to IN_PROGRESS
        // instead of in this method.
        if (row == null) {
            addScheduleRow(schedule);
            sendNextUpdateMessage(System.currentTimeMillis());
        }
    }

    /**
     * Called when a schedule recording is removed from dvr date manager.
     */
    public void onScheduledRecordingRemoved(ScheduledRecording schedule) {
        if (DEBUG) Log.d(TAG, "onScheduledRecordingRemoved: " + schedule);
        ScheduleRow row = findRowByScheduledRecording(schedule);
        if (row != null) {
            removeScheduleRow(row);
            notifyArrayItemRangeChanged(indexOf(row), 1);
            sendNextUpdateMessage(System.currentTimeMillis());
        }
    }

    /**
     * Called when a schedule recording is updated in dvr date manager.
     */
    public void onScheduledRecordingUpdated(ScheduledRecording schedule, boolean conflictChange) {
        if (DEBUG) Log.d(TAG, "onScheduledRecordingUpdated: " + schedule);
        ScheduleRow row = findRowByScheduledRecording(schedule);
        if (row != null) {
            if (conflictChange && isStartOrStopRequested()) {
                // Delay the conflict update until it gets the response of the start/stop request.
                // The purpose is to avoid the intermediate conflict change.
                addPendingUpdate(row);
                return;
            }
            if (row.isStopRecordingRequested()) {
                // Wait until the recording is finished
                if (schedule.getState() == ScheduledRecording.STATE_RECORDING_FINISHED
                        || schedule.getState() == ScheduledRecording.STATE_RECORDING_CLIPPED
                        || schedule.getState() == ScheduledRecording.STATE_RECORDING_FAILED) {
                    row.setStopRecordingRequested(false);
                    if (!isStartOrStopRequested()) {
                        executePendingUpdate();
                    }
                    row.setSchedule(schedule);
                }
            } else {
                row.setSchedule(schedule);
                if (!willBeKept(schedule)) {
                    removeScheduleRow(row);
                }
            }
            notifyArrayItemRangeChanged(indexOf(row), 1);
            sendNextUpdateMessage(System.currentTimeMillis());
        } else {
            row = findRowWithStartRequest(schedule);
            // When the start recording was requested, we give the highest priority. So it is
            // guaranteed that the state will be changed from NOT_STARTED to the other state.
            // Update the row with the next state not to show the intermediate state which causes
            // blinking.
            if (row != null
                    && schedule.getState() != ScheduledRecording.STATE_RECORDING_NOT_STARTED) {
                // This can be called multiple times, so do not call
                // ScheduleRow.setStartRecordingRequested(false) here.
                row.setStartRecordingRequested(false);
                if (!isStartOrStopRequested()) {
                    executePendingUpdate();
                }
                row.setSchedule(schedule);
                notifyArrayItemRangeChanged(indexOf(row), 1);
                sendNextUpdateMessage(System.currentTimeMillis());
            }
        }
    }

    /**
     * Checks if there is a row which requested start/stop recording.
     */
    protected boolean isStartOrStopRequested() {
        for (int i = 0; i < size(); i++) {
            Object item = get(i);
            if (item instanceof ScheduleRow) {
                ScheduleRow row = (ScheduleRow) item;
                if (row.isStartRecordingRequested() || row.isStopRecordingRequested()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Delays update of the row.
     */
    protected void addPendingUpdate(ScheduleRow row) {
        mPendingUpdate.add(row);
    }

    /**
     * Executes the pending updates.
     */
    protected void executePendingUpdate() {
        for (ScheduleRow row : mPendingUpdate) {
            int index = indexOf(row);
            if (index != -1) {
                notifyArrayItemRangeChanged(index, 1);
            }
        }
        mPendingUpdate.clear();
    }

    /**
     * To check whether the recording should be kept or not.
     */
    protected boolean willBeKept(ScheduledRecording schedule) {
        // CANCELED state means that the schedule was removed temporarily, which should be shown
        // in the list so that the user can reschedule it.
        return schedule.getEndTimeMs() > System.currentTimeMillis()
                && (schedule.getState() == ScheduledRecording.STATE_RECORDING_IN_PROGRESS
                || schedule.getState() == ScheduledRecording.STATE_RECORDING_NOT_STARTED
                || schedule.getState() == ScheduledRecording.STATE_RECORDING_CANCELED);
    }

    /**
     * Handle the message to update/remove rows.
     */
    protected void handleUpdateRow(long currentTimeMs) {
        for (int i = 0; i < size(); i++) {
            Object item = get(i);
            if (item instanceof ScheduleRow) {
                ScheduleRow row = (ScheduleRow) item;
                if (row.getEndTimeMs() <= currentTimeMs) {
                    removeScheduleRow(row);
                }
            }
        }
    }

    /**
     * Returns the next update time. Return {@link Long#MAX_VALUE} if no timer is necessary.
     */
    protected long getNextTimerMs(long currentTimeMs) {
        long earliest = Long.MAX_VALUE;
        for (int i = 0; i < size(); i++) {
            Object item = get(i);
            if (item instanceof ScheduleRow) {
                // If the schedule was finished earlier than the end time, it should be removed
                // when it reaches the end time in this class.
                ScheduleRow row = (ScheduleRow) item;
                if (earliest > row.getEndTimeMs()) {
                    earliest = row.getEndTimeMs();
                }
            }
        }
        return earliest;
    }

    /**
     * Send update message at the time returned by {@link #getNextTimerMs}.
     */
    protected final void sendNextUpdateMessage(long currentTimeMs) {
        mHandler.removeMessages(MSG_UPDATE_ROW);
        long nextTime = getNextTimerMs(currentTimeMs);
        if (nextTime != Long.MAX_VALUE) {
            mHandler.sendEmptyMessageDelayed(MSG_UPDATE_ROW,
                    nextTime - System.currentTimeMillis());
        }
    }
}
