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

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Range;

import com.android.tv.R;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.dvr.provider.DvrContract.Schedules;
import com.android.tv.util.CompositeComparator;
import com.android.tv.util.Utils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.Comparator;
import java.util.Objects;

/**
 * A data class for one recording contents.
 */
@VisibleForTesting
public final class ScheduledRecording implements Parcelable {
    private static final String TAG = "ScheduledRecording";

    /**
     * Indicates that the ID is not assigned yet.
     */
    public static final long ID_NOT_SET = 0;

    /**
     * The default priority of the recording.
     */
    public static final long DEFAULT_PRIORITY = Long.MAX_VALUE >> 1;

    /**
     * Compares the start time in ascending order.
     */
    public static final Comparator<ScheduledRecording> START_TIME_COMPARATOR
            = new Comparator<ScheduledRecording>() {
        @Override
        public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
            return Long.compare(lhs.mStartTimeMs, rhs.mStartTimeMs);
        }
    };

    /**
     * Compares the end time in ascending order.
     */
    public static final Comparator<ScheduledRecording> END_TIME_COMPARATOR
            = new Comparator<ScheduledRecording>() {
        @Override
        public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
            return Long.compare(lhs.mEndTimeMs, rhs.mEndTimeMs);
        }
    };

    /**
     * Compares ID in ascending order. The schedule with the larger ID was created later.
     */
    public static final Comparator<ScheduledRecording> ID_COMPARATOR
            = new Comparator<ScheduledRecording>() {
        @Override
        public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
            return Long.compare(lhs.mId, rhs.mId);
        }
    };

    /**
     * Compares the priority in ascending order.
     */
    public static final Comparator<ScheduledRecording> PRIORITY_COMPARATOR
            = new Comparator<ScheduledRecording>() {
        @Override
        public int compare(ScheduledRecording lhs, ScheduledRecording rhs) {
            return Long.compare(lhs.mPriority, rhs.mPriority);
        }
    };

    /**
     * Compares start time in ascending order and then priority in descending order and then ID in
     * descending order.
     */
    public static final Comparator<ScheduledRecording> START_TIME_THEN_PRIORITY_THEN_ID_COMPARATOR
            = new CompositeComparator<>(START_TIME_COMPARATOR, PRIORITY_COMPARATOR.reversed(),
            ID_COMPARATOR.reversed());

    /**
     * Builds scheduled recordings from programs.
     */
    public static Builder builder(String inputId, Program p) {
        return new Builder()
                .setInputId(inputId)
                .setChannelId(p.getChannelId())
                .setStartTimeMs(p.getStartTimeUtcMillis()).setEndTimeMs(p.getEndTimeUtcMillis())
                .setProgramId(p.getId())
                .setProgramTitle(p.getTitle())
                .setSeasonNumber(p.getSeasonNumber())
                .setEpisodeNumber(p.getEpisodeNumber())
                .setEpisodeTitle(p.getEpisodeTitle())
                .setProgramDescription(p.getDescription())
                .setProgramLongDescription(p.getLongDescription())
                .setProgramPosterArtUri(p.getPosterArtUri())
                .setProgramThumbnailUri(p.getThumbnailUri())
                .setType(TYPE_PROGRAM);
    }

    public static Builder builder(String inputId, long channelId, long startTime, long endTime) {
        return new Builder()
                .setInputId(inputId)
                .setChannelId(channelId)
                .setStartTimeMs(startTime)
                .setEndTimeMs(endTime)
                .setType(TYPE_TIMED);
    }

    /**
     * Creates a new Builder with the values set from the {@link RecordedProgram}.
     */
    @VisibleForTesting
    public static Builder builder(RecordedProgram p) {
        boolean isProgramRecording = !TextUtils.isEmpty(p.getTitle());
        return new Builder()
                .setInputId(p.getInputId())
                .setChannelId(p.getChannelId())
                .setType(isProgramRecording ? TYPE_PROGRAM : TYPE_TIMED)
                .setStartTimeMs(p.getStartTimeUtcMillis())
                .setEndTimeMs(p.getEndTimeUtcMillis())
                .setProgramTitle(p.getTitle())
                .setSeasonNumber(p.getSeasonNumber())
                .setEpisodeNumber(p.getEpisodeNumber())
                .setEpisodeTitle(p.getEpisodeTitle())
                .setProgramDescription(p.getDescription())
                .setProgramLongDescription(p.getLongDescription())
                .setProgramPosterArtUri(p.getPosterArtUri())
                .setProgramThumbnailUri(p.getThumbnailUri())
                .setState(STATE_RECORDING_FINISHED);
    }

    public static final class Builder {
        private long mId = ID_NOT_SET;
        private long mPriority = DvrScheduleManager.DEFAULT_PRIORITY;
        private String mInputId;
        private long mChannelId;
        private long mProgramId = ID_NOT_SET;
        private String mProgramTitle;
        private @RecordingType int mType;
        private long mStartTimeMs;
        private long mEndTimeMs;
        private String mSeasonNumber;
        private String mEpisodeNumber;
        private String mEpisodeTitle;
        private String mProgramDescription;
        private String mProgramLongDescription;
        private String mProgramPosterArtUri;
        private String mProgramThumbnailUri;
        private @RecordingState int mState;
        private long mSeriesRecordingId = ID_NOT_SET;

        private Builder() { }

        public Builder setId(long id) {
            mId = id;
            return this;
        }

        public Builder setPriority(long priority) {
            mPriority = priority;
            return this;
        }

        public Builder setInputId(String inputId) {
            mInputId = inputId;
            return this;
        }

        public Builder setChannelId(long channelId) {
            mChannelId = channelId;
            return this;
        }

        public Builder setProgramId(long programId) {
            mProgramId = programId;
            return this;
        }

        public Builder setProgramTitle(String programTitle) {
            mProgramTitle = programTitle;
            return this;
        }

        private Builder setType(@RecordingType int type) {
            mType = type;
            return this;
        }

        public Builder setStartTimeMs(long startTimeMs) {
            mStartTimeMs = startTimeMs;
            return this;
        }

        public Builder setEndTimeMs(long endTimeMs) {
            mEndTimeMs = endTimeMs;
            return this;
        }

        public Builder setSeasonNumber(String seasonNumber) {
            mSeasonNumber = seasonNumber;
            return this;
        }

        public Builder setEpisodeNumber(String episodeNumber) {
            mEpisodeNumber = episodeNumber;
            return this;
        }

        public Builder setEpisodeTitle(String episodeTitle) {
            mEpisodeTitle = episodeTitle;
            return this;
        }

        public Builder setProgramDescription(String description) {
            mProgramDescription = description;
            return this;
        }

        public Builder setProgramLongDescription(String longDescription) {
            mProgramLongDescription = longDescription;
            return this;
        }

        public Builder setProgramPosterArtUri(String programPosterArtUri) {
            mProgramPosterArtUri = programPosterArtUri;
            return this;
        }

        public Builder setProgramThumbnailUri(String programThumbnailUri) {
            mProgramThumbnailUri = programThumbnailUri;
            return this;
        }

        public Builder setState(@RecordingState int state) {
            mState = state;
            return this;
        }

        public Builder setSeriesRecordingId(long seriesRecordingId) {
            mSeriesRecordingId = seriesRecordingId;
            return this;
        }

        public ScheduledRecording build() {
            return new ScheduledRecording(mId, mPriority, mInputId, mChannelId, mProgramId,
                    mProgramTitle, mType, mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber,
                    mEpisodeTitle, mProgramDescription, mProgramLongDescription,
                    mProgramPosterArtUri, mProgramThumbnailUri, mState, mSeriesRecordingId);
        }
    }

    /**
     * Creates {@link Builder} object from the given original {@code Recording}.
     */
    public static Builder buildFrom(ScheduledRecording orig) {
        return new Builder()
                .setId(orig.mId)
                .setInputId(orig.mInputId)
                .setChannelId(orig.mChannelId)
                .setEndTimeMs(orig.mEndTimeMs)
                .setSeriesRecordingId(orig.mSeriesRecordingId)
                .setPriority(orig.mPriority)
                .setProgramId(orig.mProgramId)
                .setProgramTitle(orig.mProgramTitle)
                .setStartTimeMs(orig.mStartTimeMs)
                .setSeasonNumber(orig.getSeasonNumber())
                .setEpisodeNumber(orig.getEpisodeNumber())
                .setEpisodeTitle(orig.getEpisodeTitle())
                .setProgramDescription(orig.getProgramDescription())
                .setProgramLongDescription(orig.getProgramLongDescription())
                .setProgramPosterArtUri(orig.getProgramPosterArtUri())
                .setProgramThumbnailUri(orig.getProgramThumbnailUri())
                .setState(orig.mState).setType(orig.mType);
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({STATE_RECORDING_NOT_STARTED, STATE_RECORDING_IN_PROGRESS, STATE_RECORDING_FINISHED,
            STATE_RECORDING_FAILED, STATE_RECORDING_CLIPPED, STATE_RECORDING_DELETED,
            STATE_RECORDING_CANCELED})
    public @interface RecordingState {}
    public static final int STATE_RECORDING_NOT_STARTED = 0;
    public static final int STATE_RECORDING_IN_PROGRESS = 1;
    public static final int STATE_RECORDING_FINISHED = 2;
    public static final int STATE_RECORDING_FAILED = 3;
    public static final int STATE_RECORDING_CLIPPED = 4;
    public static final int STATE_RECORDING_DELETED = 5;
    public static final int STATE_RECORDING_CANCELED = 6;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TYPE_TIMED, TYPE_PROGRAM})
    public @interface RecordingType {}
    /**
     * Record with given time range.
     */
    public static final int TYPE_TIMED = 1;
    /**
     * Record with a given program.
     */
    public static final int TYPE_PROGRAM = 2;

    @RecordingType private final int mType;

    /**
     * Use this projection if you want to create {@link ScheduledRecording} object using
     * {@link #fromCursor}.
     */
    public static final String[] PROJECTION = {
            // Columns must match what is read in #fromCursor
            Schedules._ID,
            Schedules.COLUMN_PRIORITY,
            Schedules.COLUMN_TYPE,
            Schedules.COLUMN_INPUT_ID,
            Schedules.COLUMN_CHANNEL_ID,
            Schedules.COLUMN_PROGRAM_ID,
            Schedules.COLUMN_PROGRAM_TITLE,
            Schedules.COLUMN_START_TIME_UTC_MILLIS,
            Schedules.COLUMN_END_TIME_UTC_MILLIS,
            Schedules.COLUMN_SEASON_NUMBER,
            Schedules.COLUMN_EPISODE_NUMBER,
            Schedules.COLUMN_EPISODE_TITLE,
            Schedules.COLUMN_PROGRAM_DESCRIPTION,
            Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION,
            Schedules.COLUMN_PROGRAM_POST_ART_URI,
            Schedules.COLUMN_PROGRAM_THUMBNAIL_URI,
            Schedules.COLUMN_STATE,
            Schedules.COLUMN_SERIES_RECORDING_ID};

    /**
     * Creates {@link ScheduledRecording} object from the given {@link Cursor}.
     */
    public static ScheduledRecording fromCursor(Cursor c) {
        int index = -1;
        return new Builder()
                .setId(c.getLong(++index))
                .setPriority(c.getLong(++index))
                .setType(recordingType(c.getString(++index)))
                .setInputId(c.getString(++index))
                .setChannelId(c.getLong(++index))
                .setProgramId(c.getLong(++index))
                .setProgramTitle(c.getString(++index))
                .setStartTimeMs(c.getLong(++index))
                .setEndTimeMs(c.getLong(++index))
                .setSeasonNumber(c.getString(++index))
                .setEpisodeNumber(c.getString(++index))
                .setEpisodeTitle(c.getString(++index))
                .setProgramDescription(c.getString(++index))
                .setProgramLongDescription(c.getString(++index))
                .setProgramPosterArtUri(c.getString(++index))
                .setProgramThumbnailUri(c.getString(++index))
                .setState(recordingState(c.getString(++index)))
                .setSeriesRecordingId(c.getLong(++index))
                .build();
    }

    public static ContentValues toContentValues(ScheduledRecording r) {
        ContentValues values = new ContentValues();
        if (r.getId() != ID_NOT_SET) {
            values.put(Schedules._ID, r.getId());
        }
        values.put(Schedules.COLUMN_INPUT_ID, r.getInputId());
        values.put(Schedules.COLUMN_CHANNEL_ID, r.getChannelId());
        values.put(Schedules.COLUMN_PROGRAM_ID, r.getProgramId());
        values.put(Schedules.COLUMN_PROGRAM_TITLE, r.getProgramTitle());
        values.put(Schedules.COLUMN_PRIORITY, r.getPriority());
        values.put(Schedules.COLUMN_START_TIME_UTC_MILLIS, r.getStartTimeMs());
        values.put(Schedules.COLUMN_END_TIME_UTC_MILLIS, r.getEndTimeMs());
        values.put(Schedules.COLUMN_SEASON_NUMBER, r.getSeasonNumber());
        values.put(Schedules.COLUMN_EPISODE_NUMBER, r.getEpisodeNumber());
        values.put(Schedules.COLUMN_EPISODE_TITLE, r.getEpisodeTitle());
        values.put(Schedules.COLUMN_PROGRAM_DESCRIPTION, r.getProgramDescription());
        values.put(Schedules.COLUMN_PROGRAM_LONG_DESCRIPTION, r.getProgramLongDescription());
        values.put(Schedules.COLUMN_PROGRAM_POST_ART_URI, r.getProgramPosterArtUri());
        values.put(Schedules.COLUMN_PROGRAM_THUMBNAIL_URI, r.getProgramThumbnailUri());
        values.put(Schedules.COLUMN_STATE, recordingState(r.getState()));
        values.put(Schedules.COLUMN_TYPE, recordingType(r.getType()));
        if (r.getSeriesRecordingId() != ID_NOT_SET) {
            values.put(Schedules.COLUMN_SERIES_RECORDING_ID, r.getSeriesRecordingId());
        } else {
            values.putNull(Schedules.COLUMN_SERIES_RECORDING_ID);
        }
        return values;
    }

    public static ScheduledRecording fromParcel(Parcel in) {
        return new Builder()
                .setId(in.readLong())
                .setPriority(in.readLong())
                .setInputId(in.readString())
                .setChannelId(in.readLong())
                .setProgramId(in.readLong())
                .setProgramTitle(in.readString())
                .setType(in.readInt())
                .setStartTimeMs(in.readLong())
                .setEndTimeMs(in.readLong())
                .setSeasonNumber(in.readString())
                .setEpisodeNumber(in.readString())
                .setEpisodeTitle(in.readString())
                .setProgramDescription(in.readString())
                .setProgramLongDescription(in.readString())
                .setProgramPosterArtUri(in.readString())
                .setProgramThumbnailUri(in.readString())
                .setState(in.readInt())
                .setSeriesRecordingId(in.readLong())
                .build();
    }

    public static final Parcelable.Creator<ScheduledRecording> CREATOR =
            new Parcelable.Creator<ScheduledRecording>() {
        @Override
        public ScheduledRecording createFromParcel(Parcel in) {
          return ScheduledRecording.fromParcel(in);
        }

        @Override
        public ScheduledRecording[] newArray(int size) {
          return new ScheduledRecording[size];
        }
    };

    /**
     * The ID internal to Live TV
     */
    private long mId;

    /**
     * The priority of this recording.
     *
     * <p> The highest number is recorded first. If there is a tie in priority then the higher id
     * wins.
     */
    private final long mPriority;

    private final String mInputId;
    private final long mChannelId;
    /**
     * Optional id of the associated program.
     */
    private final long mProgramId;
    private final String mProgramTitle;

    private final long mStartTimeMs;
    private final long mEndTimeMs;
    private final String mSeasonNumber;
    private final String mEpisodeNumber;
    private final String mEpisodeTitle;
    private final String mProgramDescription;
    private final String mProgramLongDescription;
    private final String mProgramPosterArtUri;
    private final String mProgramThumbnailUri;
    @RecordingState private final int mState;
    private final long mSeriesRecordingId;

    private ScheduledRecording(long id, long priority, String inputId, long channelId, long programId,
            String programTitle, @RecordingType int type, long startTime, long endTime,
            String seasonNumber, String episodeNumber, String episodeTitle,
            String programDescription, String programLongDescription, String programPosterArtUri,
            String programThumbnailUri, @RecordingState int state, long seriesRecordingId) {
        mId = id;
        mPriority = priority;
        mInputId = inputId;
        mChannelId = channelId;
        mProgramId = programId;
        mProgramTitle = programTitle;
        mType = type;
        mStartTimeMs = startTime;
        mEndTimeMs = endTime;
        mSeasonNumber = seasonNumber;
        mEpisodeNumber = episodeNumber;
        mEpisodeTitle = episodeTitle;
        mProgramDescription = programDescription;
        mProgramLongDescription = programLongDescription;
        mProgramPosterArtUri = programPosterArtUri;
        mProgramThumbnailUri = programThumbnailUri;
        mState = state;
        mSeriesRecordingId = seriesRecordingId;
    }

    /**
     * Returns recording schedule type. The possible types are {@link #TYPE_PROGRAM} and
     * {@link #TYPE_TIMED}.
     */
    @RecordingType
    public int getType() {
        return mType;
    }

    /**
     * Returns schedules' input id.
     */
    public String getInputId() {
        return mInputId;
    }

    /**
     * Returns recorded {@link Channel}.
     */
    public long getChannelId() {
        return mChannelId;
    }

    /**
     * Return the optional program id
     */
    public long getProgramId() {
        return mProgramId;
    }

    /**
     * Return the optional program Title
     */
    public String getProgramTitle() {
        return mProgramTitle;
    }

    /**
     * Returns started time.
     */
    public long getStartTimeMs() {
        return mStartTimeMs;
    }

    /**
     * Returns ended time.
     */
    public long getEndTimeMs() {
        return mEndTimeMs;
    }

    /**
     * Returns the season number.
     */
    public String getSeasonNumber() {
        return mSeasonNumber;
    }

    /**
     * Returns the episode number.
     */
    public String getEpisodeNumber() {
        return mEpisodeNumber;
    }

    /**
     * Returns the episode title.
     */
    public String getEpisodeTitle() {
        return mEpisodeTitle;
    }

    /**
     * Returns the description of program.
     */
    public String getProgramDescription() {
        return mProgramDescription;
    }

    /**
     * Returns the long description of program.
     */
    public String getProgramLongDescription() {
        return mProgramLongDescription;
    }

    /**
     * Returns the poster uri of program.
     */
    public String getProgramPosterArtUri() {
        return mProgramPosterArtUri;
    }

    /**
     * Returns the thumb nail uri of program.
     */
    public String getProgramThumbnailUri() {
        return mProgramThumbnailUri;
    }

    /**
     * Returns duration.
     */
    public long getDuration() {
        return mEndTimeMs - mStartTimeMs;
    }

    /**
     * Returns the state. The possible states are {@link #STATE_RECORDING_NOT_STARTED},
     * {@link #STATE_RECORDING_IN_PROGRESS}, {@link #STATE_RECORDING_FINISHED},
     * {@link #STATE_RECORDING_FAILED}, {@link #STATE_RECORDING_CLIPPED} and
     * {@link #STATE_RECORDING_DELETED}.
     */
    @RecordingState public int getState() {
        return mState;
    }

    /**
     * Returns the ID of the {@link SeriesRecording} including this schedule.
     */
    public long getSeriesRecordingId() {
        return mSeriesRecordingId;
    }

    public long getId() {
        return mId;
    }

    /**
     * Sets the ID;
     */
    public void setId(long id) {
        mId = id;
    }

    public long getPriority() {
        return mPriority;
    }

    /**
     * Returns season number, episode number and episode title for display.
     */
    public String getEpisodeDisplayTitle(Context context) {
        if (!TextUtils.isEmpty(mEpisodeNumber)) {
            String episodeTitle = mEpisodeTitle == null ? "" : mEpisodeTitle;
            if (TextUtils.equals(mSeasonNumber, "0")) {
                // Do not show "S0: ".
                return String.format(context.getResources().getString(
                        R.string.display_episode_title_format_no_season_number),
                        mEpisodeNumber, episodeTitle);
            } else {
                return String.format(context.getResources().getString(
                        R.string.display_episode_title_format),
                        mSeasonNumber, mEpisodeNumber, episodeTitle);
            }
        }
        return mEpisodeTitle;
    }

    /**
     * Returns the program's title withe its season and episode number.
     */
    public String getProgramTitleWithEpisodeNumber(Context context) {
        if (TextUtils.isEmpty(mProgramTitle)) {
            return mProgramTitle;
        }
        if (TextUtils.isEmpty(mSeasonNumber) || mSeasonNumber.equals("0")) {
            return TextUtils.isEmpty(mEpisodeNumber) ? mProgramTitle : context.getString(
                    R.string.program_title_with_episode_number_no_season, mProgramTitle,
                    mEpisodeNumber);
        } else {
            return context.getString(R.string.program_title_with_episode_number, mProgramTitle,
                    mSeasonNumber, mEpisodeNumber);
        }
    }


    /**
     * Converts a string to a @RecordingType int, defaulting to {@link #TYPE_TIMED}.
     */
    private static @RecordingType int recordingType(String type) {
        switch (type) {
            case Schedules.TYPE_TIMED:
                return TYPE_TIMED;
            case Schedules.TYPE_PROGRAM:
                return TYPE_PROGRAM;
            default:
                SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
                return TYPE_TIMED;
        }
    }

    /**
     * Converts a @RecordingType int to a string, defaulting to {@link Schedules#TYPE_TIMED}.
     */
    private static String recordingType(@RecordingType int type) {
        switch (type) {
            case TYPE_TIMED:
                return Schedules.TYPE_TIMED;
            case TYPE_PROGRAM:
                return Schedules.TYPE_PROGRAM;
            default:
                SoftPreconditions.checkArgument(false, TAG, "Unknown recording type " + type);
                return Schedules.TYPE_TIMED;
        }
    }

    /**
     * Converts a string to a @RecordingState int, defaulting to
     * {@link #STATE_RECORDING_NOT_STARTED}.
     */
    private static @RecordingState int recordingState(String state) {
        switch (state) {
            case Schedules.STATE_RECORDING_NOT_STARTED:
                return STATE_RECORDING_NOT_STARTED;
            case Schedules.STATE_RECORDING_IN_PROGRESS:
                return STATE_RECORDING_IN_PROGRESS;
            case Schedules.STATE_RECORDING_FINISHED:
                return STATE_RECORDING_FINISHED;
            case Schedules.STATE_RECORDING_FAILED:
                return STATE_RECORDING_FAILED;
            case Schedules.STATE_RECORDING_CLIPPED:
                return STATE_RECORDING_CLIPPED;
            case Schedules.STATE_RECORDING_DELETED:
                return STATE_RECORDING_DELETED;
            case Schedules.STATE_RECORDING_CANCELED:
                return STATE_RECORDING_CANCELED;
            default:
                SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
                return STATE_RECORDING_NOT_STARTED;
        }
    }

    /**
     * Converts a @RecordingState int to string, defaulting to
     * {@link Schedules#STATE_RECORDING_NOT_STARTED}.
     */
    private static String recordingState(@RecordingState int state) {
        switch (state) {
            case STATE_RECORDING_NOT_STARTED:
                return Schedules.STATE_RECORDING_NOT_STARTED;
            case STATE_RECORDING_IN_PROGRESS:
                return Schedules.STATE_RECORDING_IN_PROGRESS;
            case STATE_RECORDING_FINISHED:
                return Schedules.STATE_RECORDING_FINISHED;
            case STATE_RECORDING_FAILED:
                return Schedules.STATE_RECORDING_FAILED;
            case STATE_RECORDING_CLIPPED:
                return Schedules.STATE_RECORDING_CLIPPED;
            case STATE_RECORDING_DELETED:
                return Schedules.STATE_RECORDING_DELETED;
            case STATE_RECORDING_CANCELED:
                return Schedules.STATE_RECORDING_CANCELED;
            default:
                SoftPreconditions.checkArgument(false, TAG, "Unknown recording state" + state);
                return Schedules.STATE_RECORDING_NOT_STARTED;
        }
    }

    /**
     * Checks if the {@code period} overlaps with the recording time.
     */
    public boolean isOverLapping(Range<Long> period) {
        return mStartTimeMs < period.getUpper() && mEndTimeMs > period.getLower();
    }

    /**
     * Checks if the {@code schedule} overlaps with this schedule.
     */
    public boolean isOverLapping(ScheduledRecording schedule) {
        return mStartTimeMs < schedule.getEndTimeMs() && mEndTimeMs > schedule.getStartTimeMs();
    }

    @Override
    public String toString() {
        return "ScheduledRecording[" + mId
                + "]"
                + "(inputId=" + mInputId
                + ",channelId=" + mChannelId
                + ",programId=" + mProgramId
                + ",programTitle=" + mProgramTitle
                + ",type=" + mType
                + ",startTime=" + Utils.toIsoDateTimeString(mStartTimeMs) + "(" + mStartTimeMs + ")"
                + ",endTime=" + Utils.toIsoDateTimeString(mEndTimeMs) + "(" + mEndTimeMs + ")"
                + ",seasonNumber=" + mSeasonNumber
                + ",episodeNumber=" + mEpisodeNumber
                + ",episodeTitle=" + mEpisodeTitle
                + ",programDescription=" + mProgramDescription
                + ",programLongDescription=" + mProgramLongDescription
                + ",programPosterArtUri=" + mProgramPosterArtUri
                + ",programThumbnailUri=" + mProgramThumbnailUri
                + ",state=" + mState
                + ",priority=" + mPriority
                + ",seriesRecordingId=" + mSeriesRecordingId
                + ")";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int paramInt) {
        out.writeLong(mId);
        out.writeLong(mPriority);
        out.writeString(mInputId);
        out.writeLong(mChannelId);
        out.writeLong(mProgramId);
        out.writeString(mProgramTitle);
        out.writeInt(mType);
        out.writeLong(mStartTimeMs);
        out.writeLong(mEndTimeMs);
        out.writeString(mSeasonNumber);
        out.writeString(mEpisodeNumber);
        out.writeString(mEpisodeTitle);
        out.writeString(mProgramDescription);
        out.writeString(mProgramLongDescription);
        out.writeString(mProgramPosterArtUri);
        out.writeString(mProgramThumbnailUri);
        out.writeInt(mState);
        out.writeLong(mSeriesRecordingId);
    }

    /**
     * Returns {@code true} if the recording is not started yet, otherwise @{code false}.
     */
    public boolean isNotStarted() {
        return mState == STATE_RECORDING_NOT_STARTED;
    }

    /**
     * Returns {@code true} if the recording is in progress, otherwise @{code false}.
     */
    public boolean isInProgress() {
        return mState == STATE_RECORDING_IN_PROGRESS;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof ScheduledRecording)) {
            return false;
        }
        ScheduledRecording r = (ScheduledRecording) obj;
        return mId == r.mId
                && mPriority == r.mPriority
                && mChannelId == r.mChannelId
                && mProgramId == r.mProgramId
                && Objects.equals(mProgramTitle, r.mProgramTitle)
                && mType == r.mType
                && mStartTimeMs == r.mStartTimeMs
                && mEndTimeMs == r.mEndTimeMs
                && Objects.equals(mSeasonNumber, r.mSeasonNumber)
                && Objects.equals(mEpisodeNumber, r.mEpisodeNumber)
                && Objects.equals(mEpisodeTitle, r.mEpisodeTitle)
                && Objects.equals(mProgramDescription, r.getProgramDescription())
                && Objects.equals(mProgramLongDescription, r.getProgramLongDescription())
                && Objects.equals(mProgramPosterArtUri, r.getProgramPosterArtUri())
                && Objects.equals(mProgramThumbnailUri, r.getProgramThumbnailUri())
                && mState == r.mState
                && mSeriesRecordingId == r.mSeriesRecordingId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mId, mPriority, mChannelId, mProgramId, mProgramTitle, mType,
                mStartTimeMs, mEndTimeMs, mSeasonNumber, mEpisodeNumber, mEpisodeTitle,
                mProgramDescription, mProgramLongDescription, mProgramPosterArtUri,
                mProgramThumbnailUri, mState, mSeriesRecordingId);
    }

    /**
     * Returns an array containing all of the elements in the list.
     */
    public static ScheduledRecording[] toArray(Collection<ScheduledRecording> schedules) {
        return schedules.toArray(new ScheduledRecording[schedules.size()]);
    }
}
