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

import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.media.tv.TvContractCompat.Programs;
import android.support.media.tv.TvContractCompat.Programs.AspectRatio;
import android.support.media.tv.TvContractCompat.Programs.Availability;
import android.support.media.tv.TvContractCompat.Programs.Genres.Genre;
import android.support.media.tv.TvContractCompat.Programs.InteractionType;
import android.support.media.tv.TvContractCompat.Programs.ReviewRatingStyle;
import android.support.media.tv.TvContractCompat.Programs.Type;
import android.support.media.tv.TvContractCompat.Programs.WatchNextType;
import android.support.v4.os.BuildCompat;
import android.text.TextUtils;

import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * A convenience class to create and insert program information into the database.
 */
public final class Program implements Comparable<Program> {
    /**
     * @hide
     */
    @RestrictTo(LIBRARY_GROUP)
    public static final String[] PROJECTION = getProjection();

    private static final long INVALID_LONG_VALUE = -1;
    private static final int INVALID_INT_VALUE = -1;
    private static final int IS_RECORDING_PROHIBITED = 1;
    private static final int IS_SEARCHABLE = 1;
    private static final int IS_TRANSIENT = 1;
    private static final int IS_LIVE = 1;

    private final long mId;
    private final long mChannelId;
    private final String mTitle;
    private final String mEpisodeTitle;
    private final String mSeasonNumber;
    private final String mEpisodeNumber;
    private final long mStartTimeUtcMillis;
    private final long mEndTimeUtcMillis;
    private final String mDescription;
    private final String mLongDescription;
    private final int mVideoWidth;
    private final int mVideoHeight;
    private final Uri mPosterArtUri;
    private final Uri mThumbnailUri;
    private final String[] mBroadcastGenres;
    private final String[] mCanonicalGenres;
    private final TvContentRating[] mContentRatings;
    private final byte[] mInternalProviderData;
    private final String[] mAudioLanguages;
    private final int mSearchable;
    private final Long mInternalProviderFlag1;
    private final Long mInternalProviderFlag2;
    private final Long mInternalProviderFlag3;
    private final Long mInternalProviderFlag4;
    private final int mRecordingProhibited;
    private final String mSeasonTitle;
    private final String mInternalProviderId;
    private final Uri mPreviewVideoUri;
    private final int mLastPlaybackPositionMillis;
    private final int mDurationMillis;
    private final Uri mAppLinkIntentUri;
    private final int mWeight;
    private final int mTransient;
    private final String mType;
    private final String mWatchNextType;
    private final String mPosterArtAspectRatio;
    private final String mThumbnailAspectRatio;
    private final Uri mLogoUri;
    private final String mAvailability;
    private final String mStartingPrice;
    private final String mOfferPrice;
    private final String mReleaseDate;
    private final int mItemCount;
    private final int mLive;
    private final String mInteractionType;
    private final int mInteractionCount;
    private final String mAuthor;
    private final String mReviewRatingStyle;
    private final String mReviewRating;

    private Program(Builder builder) {
        mId = builder.mId;
        mChannelId = builder.mChannelId;
        mTitle = builder.mTitle;
        mEpisodeTitle = builder.mEpisodeTitle;
        mSeasonNumber = builder.mSeasonNumber;
        mEpisodeNumber = builder.mEpisodeNumber;
        mStartTimeUtcMillis = builder.mStartTimeUtcMillis;
        mEndTimeUtcMillis = builder.mEndTimeUtcMillis;
        mDescription = builder.mDescription;
        mLongDescription = builder.mLongDescription;
        mVideoWidth = builder.mVideoWidth;
        mVideoHeight = builder.mVideoHeight;
        mPosterArtUri = builder.mPosterArtUri;
        mThumbnailUri = builder.mThumbnailUri;
        mBroadcastGenres = builder.mBroadcastGenres;
        mCanonicalGenres = builder.mCanonicalGenres;
        mContentRatings = builder.mContentRatings;
        mInternalProviderData = builder.mInternalProviderData;
        mAudioLanguages = builder.mAudioLanguages;
        mSearchable = builder.mSearchable;
        mInternalProviderFlag1 = builder.mInternalProviderFlag1;
        mInternalProviderFlag2 = builder.mInternalProviderFlag2;
        mInternalProviderFlag3 = builder.mInternalProviderFlag3;
        mInternalProviderFlag4 = builder.mInternalProviderFlag4;
        mRecordingProhibited = builder.mRecordingProhibited;
        mSeasonTitle = builder.mSeasonTitle;
        mInternalProviderId = builder.mExternalId;
        mPreviewVideoUri = builder.mPreviewVideoUri;
        mLastPlaybackPositionMillis = builder.mLastPlaybackPositionMillis;
        mDurationMillis = builder.mDurationMillis;
        mAppLinkIntentUri = builder.mAppLinkIntentUri;
        mWeight = builder.mWeight;
        mTransient = builder.mTransient;
        mType = builder.mType;
        mWatchNextType = builder.mWatchNextType;
        mPosterArtAspectRatio = builder.mPosterArtAspectRatio;
        mThumbnailAspectRatio = builder.mThumbnailAspectRatio;
        mLogoUri = builder.mLogoUri;
        mAvailability = builder.mAvailability;
        mStartingPrice = builder.mStartingPrice;
        mOfferPrice = builder.mOfferPrice;
        mReleaseDate = builder.mReleaseDate;
        mItemCount = builder.mItemCount;
        mLive = builder.mLive;
        mInteractionType = builder.mInteractionType;
        mInteractionCount = builder.mInteractionCount;
        mAuthor = builder.mAuthor;
        mReviewRatingStyle = builder.mReviewRatingStyle;
        mReviewRating = builder.mReviewRating;
    }

    /**
     * @return The value of {@link Programs#_ID} for the program.
     */
    public long getId() {
        return mId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CHANNEL_ID} for the program.
     */
    public long getChannelId() {
        return mChannelId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TITLE} for the program.
     */
    public String getTitle() {
        return mTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_EPISODE_TITLE} for the program.
     */
    public String getEpisodeTitle() {
        return mEpisodeTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEASON_DISPLAY_NUMBER} for the program.
     */
    public String getSeasonNumber() {
        return mSeasonNumber;
    }

    /**
     * @return The value of {@link Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program.
     */
    public String getEpisodeNumber() {
        return mEpisodeNumber;
    }

    /**
     * @return The value of {@link Programs#COLUMN_START_TIME_UTC_MILLIS} for the program.
     */
    public long getStartTimeUtcMillis() {
        return mStartTimeUtcMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_END_TIME_UTC_MILLIS} for the program.
     */
    public long getEndTimeUtcMillis() {
        return mEndTimeUtcMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SHORT_DESCRIPTION} for the program.
     */
    public String getDescription() {
        return mDescription;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LONG_DESCRIPTION} for the program.
     */
    public String getLongDescription() {
        return mLongDescription;
    }

    /**
     * @return The value of {@link Programs#COLUMN_VIDEO_WIDTH} for the program.
     */
    public int getVideoWidth() {
        return mVideoWidth;
    }

    /**
     * @return The value of {@link Programs#COLUMN_VIDEO_HEIGHT} for the program.
     */
    public int getVideoHeight() {
        return mVideoHeight;
    }

    /**
     * @return The value of {@link Programs#COLUMN_BROADCAST_GENRE} for the program.
     */
    public String[] getBroadcastGenres() {
        return mBroadcastGenres;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CANONICAL_GENRE} for the program.
     */
    public @Genre String[] getCanonicalGenres() {
        return mCanonicalGenres;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CONTENT_RATING} for the program.
     */
    public TvContentRating[] getContentRatings() {
        return mContentRatings;
    }

    /**
     * @return The value of {@link Programs#COLUMN_POSTER_ART_URI} for the program.
     */
    public Uri getPosterArtUri() {
        return mPosterArtUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_THUMBNAIL_URI} for the program.
     */
    public Uri getThumbnailUri() {
        return mThumbnailUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the program.
     */
    public byte[] getInternalProviderDataByteArray() {
        return mInternalProviderData;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AUDIO_LANGUAGE} for the program.
     */
    public String[] getAudioLanguages() {
        return mAudioLanguages;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEARCHABLE} for the program.
     */
    public boolean isSearchable() {
        return mSearchable == IS_SEARCHABLE || mSearchable == INVALID_INT_VALUE;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG1} for the program.
     */
    public Long getInternalProviderFlag1() {
        return mInternalProviderFlag1;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG2} for the program.
     */
    public Long getInternalProviderFlag2() {
        return mInternalProviderFlag2;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG3} for the program.
     */
    public Long getInternalProviderFlag3() {
        return mInternalProviderFlag3;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG4} for the program.
     */
    public Long getInternalProviderFlag4() {
        return mInternalProviderFlag4;
    }

    /**
     * @return The value of {@link Programs#COLUMN_RECORDING_PROHIBITED} for the program.
     */
    public boolean isRecordingProhibited() {
        return mRecordingProhibited == IS_RECORDING_PROHIBITED;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEASON_TITLE} for the program.
     */
    public String getSeasonTitle() {
        return mSeasonTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_ID} for the program.
     */
    public String getInternalProviderId() {
        return mInternalProviderId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_PREVIEW_VIDEO_URI} for the program.
     */
    public Uri getPreviewVideoUri() {
        return mPreviewVideoUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LAST_PLAYBACK_POSITION_MILLIS} for the program.
     */
    public int getLastPlaybackPositionMillis() {
        return mLastPlaybackPositionMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_DURATION_MILLIS} for the program.
     */
    public int getDurationMillis() {
        return mDurationMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
     */
    public Uri getAppLinkIntentUri() {
        return mAppLinkIntentUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
     */
    public Intent getAppLinkIntent() throws URISyntaxException {
        return Intent.parseUri(mAppLinkIntentUri.toString(), Intent.URI_INTENT_SCHEME);
    }

    /**
     * @return The value of {@link Programs#COLUMN_WEIGHT} for the program.
     */
    public int getWeight() {
        return mWeight;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TRANSIENT} for the program.
     * @hide
     */
    @RestrictTo(LIBRARY_GROUP)
    public boolean isTransient() {
        return mTransient == IS_TRANSIENT;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TYPE} for the program.
     */
    public @Type String getType() {
        return mType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_WATCH_NEXT_TYPE} for the program.
     */
    public @WatchNextType String getWatchNextType() {
        return mWatchNextType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_POSTER_ART_ASPECT_RATIO} for the program.
     */
    public @AspectRatio String getPosterArtAspectRatio() {
        return mPosterArtAspectRatio;
    }

    /**
     * @return The value of {@link Programs#COLUMN_THUMBNAIL_ASPECT_RATIO} for the program.
     */
    public @AspectRatio String getThumbnailAspectRatio() {
        return mThumbnailAspectRatio;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LOGO_URI} for the program.
     */
    public Uri getLogoUri() {
        return mLogoUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
     */
    public @Availability String getAvailability() {
        return mAvailability;
    }

    /**
     * @return The value of {@link Programs#COLUMN_STARTING_PRICE} for the program.
     */
    public String getStartingPrice() {
        return mStartingPrice;
    }

    /**
     * @return The value of {@link Programs#COLUMN_OFFER_PRICE} for the program.
     */
    public String getOfferPrice() {
        return mOfferPrice;
    }

    /**
     * @return The value of {@link Programs#COLUMN_RELEASE_DATE} for the program.
     */
    public String getReleaseDate() {
        return mReleaseDate;
    }

    /**
     * @return The value of {@link Programs#COLUMN_ITEM_COUNT} for the program.
     */
    public int getItemCount() {
        return mItemCount;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LIVE} for the program.
     */
    public boolean isLive() {
        return mLive == IS_LIVE;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERACTION_TYPE} for the program.
     */
    public @InteractionType String getInteractionType() {
        return mInteractionType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERACTION_COUNT} for the program.
     */
    public int getInteractionCount() {
        return mInteractionCount;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AUTHOR} for the program.
     */
    public String getAuthor() {
        return mAuthor;
    }

    /**
     * @return The value of {@link Programs#COLUMN_REVIEW_RATING_STYLE} for the program.
     */
    public @ReviewRatingStyle String getReviewRatingStyle() {
        return mReviewRatingStyle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_REVIEW_RATING} for the program.
     */
    public String getReviewRating() {
        return mReviewRating;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis,
                mTitle, mEpisodeTitle, mDescription, mLongDescription, mVideoWidth, mVideoHeight,
                mPosterArtUri, mThumbnailUri, mContentRatings, mCanonicalGenres, mSeasonNumber,
                mEpisodeNumber);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Program)) {
            return false;
        }
        Program program = (Program) other;
        return mChannelId == program.mChannelId
                && mStartTimeUtcMillis == program.mStartTimeUtcMillis
                && mEndTimeUtcMillis == program.mEndTimeUtcMillis
                && Objects.equals(mTitle, program.mTitle)
                && Objects.equals(mEpisodeTitle, program.mEpisodeTitle)
                && Objects.equals(mSeasonNumber, program.mSeasonNumber)
                && Objects.equals(mEpisodeNumber, program.mEpisodeNumber)
                && Objects.equals(mDescription, program.mDescription)
                && Objects.equals(mLongDescription, program.mLongDescription)
                && mVideoWidth == program.mVideoWidth
                && mVideoHeight == program.mVideoHeight
                && Objects.equals(mPosterArtUri, program.mPosterArtUri)
                && Objects.equals(mThumbnailUri, program.mThumbnailUri)<commit_msg>tv-provider: use Arrays.hashCode for arrays<commit_after>/*
 * 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.support.media.tv;

import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.media.tv.TvContentRating;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.media.tv.TvContractCompat.Programs;
import android.support.media.tv.TvContractCompat.Programs.AspectRatio;
import android.support.media.tv.TvContractCompat.Programs.Availability;
import android.support.media.tv.TvContractCompat.Programs.Genres.Genre;
import android.support.media.tv.TvContractCompat.Programs.InteractionType;
import android.support.media.tv.TvContractCompat.Programs.ReviewRatingStyle;
import android.support.media.tv.TvContractCompat.Programs.Type;
import android.support.media.tv.TvContractCompat.Programs.WatchNextType;
import android.support.v4.os.BuildCompat;
import android.text.TextUtils;

import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * A convenience class to create and insert program information into the database.
 */
public final class Program implements Comparable<Program> {
    /**
     * @hide
     */
    @RestrictTo(LIBRARY_GROUP)
    public static final String[] PROJECTION = getProjection();

    private static final long INVALID_LONG_VALUE = -1;
    private static final int INVALID_INT_VALUE = -1;
    private static final int IS_RECORDING_PROHIBITED = 1;
    private static final int IS_SEARCHABLE = 1;
    private static final int IS_TRANSIENT = 1;
    private static final int IS_LIVE = 1;

    private final long mId;
    private final long mChannelId;
    private final String mTitle;
    private final String mEpisodeTitle;
    private final String mSeasonNumber;
    private final String mEpisodeNumber;
    private final long mStartTimeUtcMillis;
    private final long mEndTimeUtcMillis;
    private final String mDescription;
    private final String mLongDescription;
    private final int mVideoWidth;
    private final int mVideoHeight;
    private final Uri mPosterArtUri;
    private final Uri mThumbnailUri;
    private final String[] mBroadcastGenres;
    private final String[] mCanonicalGenres;
    private final TvContentRating[] mContentRatings;
    private final byte[] mInternalProviderData;
    private final String[] mAudioLanguages;
    private final int mSearchable;
    private final Long mInternalProviderFlag1;
    private final Long mInternalProviderFlag2;
    private final Long mInternalProviderFlag3;
    private final Long mInternalProviderFlag4;
    private final int mRecordingProhibited;
    private final String mSeasonTitle;
    private final String mInternalProviderId;
    private final Uri mPreviewVideoUri;
    private final int mLastPlaybackPositionMillis;
    private final int mDurationMillis;
    private final Uri mAppLinkIntentUri;
    private final int mWeight;
    private final int mTransient;
    private final String mType;
    private final String mWatchNextType;
    private final String mPosterArtAspectRatio;
    private final String mThumbnailAspectRatio;
    private final Uri mLogoUri;
    private final String mAvailability;
    private final String mStartingPrice;
    private final String mOfferPrice;
    private final String mReleaseDate;
    private final int mItemCount;
    private final int mLive;
    private final String mInteractionType;
    private final int mInteractionCount;
    private final String mAuthor;
    private final String mReviewRatingStyle;
    private final String mReviewRating;

    private Program(Builder builder) {
        mId = builder.mId;
        mChannelId = builder.mChannelId;
        mTitle = builder.mTitle;
        mEpisodeTitle = builder.mEpisodeTitle;
        mSeasonNumber = builder.mSeasonNumber;
        mEpisodeNumber = builder.mEpisodeNumber;
        mStartTimeUtcMillis = builder.mStartTimeUtcMillis;
        mEndTimeUtcMillis = builder.mEndTimeUtcMillis;
        mDescription = builder.mDescription;
        mLongDescription = builder.mLongDescription;
        mVideoWidth = builder.mVideoWidth;
        mVideoHeight = builder.mVideoHeight;
        mPosterArtUri = builder.mPosterArtUri;
        mThumbnailUri = builder.mThumbnailUri;
        mBroadcastGenres = builder.mBroadcastGenres;
        mCanonicalGenres = builder.mCanonicalGenres;
        mContentRatings = builder.mContentRatings;
        mInternalProviderData = builder.mInternalProviderData;
        mAudioLanguages = builder.mAudioLanguages;
        mSearchable = builder.mSearchable;
        mInternalProviderFlag1 = builder.mInternalProviderFlag1;
        mInternalProviderFlag2 = builder.mInternalProviderFlag2;
        mInternalProviderFlag3 = builder.mInternalProviderFlag3;
        mInternalProviderFlag4 = builder.mInternalProviderFlag4;
        mRecordingProhibited = builder.mRecordingProhibited;
        mSeasonTitle = builder.mSeasonTitle;
        mInternalProviderId = builder.mExternalId;
        mPreviewVideoUri = builder.mPreviewVideoUri;
        mLastPlaybackPositionMillis = builder.mLastPlaybackPositionMillis;
        mDurationMillis = builder.mDurationMillis;
        mAppLinkIntentUri = builder.mAppLinkIntentUri;
        mWeight = builder.mWeight;
        mTransient = builder.mTransient;
        mType = builder.mType;
        mWatchNextType = builder.mWatchNextType;
        mPosterArtAspectRatio = builder.mPosterArtAspectRatio;
        mThumbnailAspectRatio = builder.mThumbnailAspectRatio;
        mLogoUri = builder.mLogoUri;
        mAvailability = builder.mAvailability;
        mStartingPrice = builder.mStartingPrice;
        mOfferPrice = builder.mOfferPrice;
        mReleaseDate = builder.mReleaseDate;
        mItemCount = builder.mItemCount;
        mLive = builder.mLive;
        mInteractionType = builder.mInteractionType;
        mInteractionCount = builder.mInteractionCount;
        mAuthor = builder.mAuthor;
        mReviewRatingStyle = builder.mReviewRatingStyle;
        mReviewRating = builder.mReviewRating;
    }

    /**
     * @return The value of {@link Programs#_ID} for the program.
     */
    public long getId() {
        return mId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CHANNEL_ID} for the program.
     */
    public long getChannelId() {
        return mChannelId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TITLE} for the program.
     */
    public String getTitle() {
        return mTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_EPISODE_TITLE} for the program.
     */
    public String getEpisodeTitle() {
        return mEpisodeTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEASON_DISPLAY_NUMBER} for the program.
     */
    public String getSeasonNumber() {
        return mSeasonNumber;
    }

    /**
     * @return The value of {@link Programs#COLUMN_EPISODE_DISPLAY_NUMBER} for the program.
     */
    public String getEpisodeNumber() {
        return mEpisodeNumber;
    }

    /**
     * @return The value of {@link Programs#COLUMN_START_TIME_UTC_MILLIS} for the program.
     */
    public long getStartTimeUtcMillis() {
        return mStartTimeUtcMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_END_TIME_UTC_MILLIS} for the program.
     */
    public long getEndTimeUtcMillis() {
        return mEndTimeUtcMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SHORT_DESCRIPTION} for the program.
     */
    public String getDescription() {
        return mDescription;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LONG_DESCRIPTION} for the program.
     */
    public String getLongDescription() {
        return mLongDescription;
    }

    /**
     * @return The value of {@link Programs#COLUMN_VIDEO_WIDTH} for the program.
     */
    public int getVideoWidth() {
        return mVideoWidth;
    }

    /**
     * @return The value of {@link Programs#COLUMN_VIDEO_HEIGHT} for the program.
     */
    public int getVideoHeight() {
        return mVideoHeight;
    }

    /**
     * @return The value of {@link Programs#COLUMN_BROADCAST_GENRE} for the program.
     */
    public String[] getBroadcastGenres() {
        return mBroadcastGenres;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CANONICAL_GENRE} for the program.
     */
    public @Genre String[] getCanonicalGenres() {
        return mCanonicalGenres;
    }

    /**
     * @return The value of {@link Programs#COLUMN_CONTENT_RATING} for the program.
     */
    public TvContentRating[] getContentRatings() {
        return mContentRatings;
    }

    /**
     * @return The value of {@link Programs#COLUMN_POSTER_ART_URI} for the program.
     */
    public Uri getPosterArtUri() {
        return mPosterArtUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_THUMBNAIL_URI} for the program.
     */
    public Uri getThumbnailUri() {
        return mThumbnailUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_DATA} for the program.
     */
    public byte[] getInternalProviderDataByteArray() {
        return mInternalProviderData;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AUDIO_LANGUAGE} for the program.
     */
    public String[] getAudioLanguages() {
        return mAudioLanguages;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEARCHABLE} for the program.
     */
    public boolean isSearchable() {
        return mSearchable == IS_SEARCHABLE || mSearchable == INVALID_INT_VALUE;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG1} for the program.
     */
    public Long getInternalProviderFlag1() {
        return mInternalProviderFlag1;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG2} for the program.
     */
    public Long getInternalProviderFlag2() {
        return mInternalProviderFlag2;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG3} for the program.
     */
    public Long getInternalProviderFlag3() {
        return mInternalProviderFlag3;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_FLAG4} for the program.
     */
    public Long getInternalProviderFlag4() {
        return mInternalProviderFlag4;
    }

    /**
     * @return The value of {@link Programs#COLUMN_RECORDING_PROHIBITED} for the program.
     */
    public boolean isRecordingProhibited() {
        return mRecordingProhibited == IS_RECORDING_PROHIBITED;
    }

    /**
     * @return The value of {@link Programs#COLUMN_SEASON_TITLE} for the program.
     */
    public String getSeasonTitle() {
        return mSeasonTitle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERNAL_PROVIDER_ID} for the program.
     */
    public String getInternalProviderId() {
        return mInternalProviderId;
    }

    /**
     * @return The value of {@link Programs#COLUMN_PREVIEW_VIDEO_URI} for the program.
     */
    public Uri getPreviewVideoUri() {
        return mPreviewVideoUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LAST_PLAYBACK_POSITION_MILLIS} for the program.
     */
    public int getLastPlaybackPositionMillis() {
        return mLastPlaybackPositionMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_DURATION_MILLIS} for the program.
     */
    public int getDurationMillis() {
        return mDurationMillis;
    }

    /**
     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
     */
    public Uri getAppLinkIntentUri() {
        return mAppLinkIntentUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_APP_LINK_INTENT_URI} for the program.
     */
    public Intent getAppLinkIntent() throws URISyntaxException {
        return Intent.parseUri(mAppLinkIntentUri.toString(), Intent.URI_INTENT_SCHEME);
    }

    /**
     * @return The value of {@link Programs#COLUMN_WEIGHT} for the program.
     */
    public int getWeight() {
        return mWeight;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TRANSIENT} for the program.
     * @hide
     */
    @RestrictTo(LIBRARY_GROUP)
    public boolean isTransient() {
        return mTransient == IS_TRANSIENT;
    }

    /**
     * @return The value of {@link Programs#COLUMN_TYPE} for the program.
     */
    public @Type String getType() {
        return mType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_WATCH_NEXT_TYPE} for the program.
     */
    public @WatchNextType String getWatchNextType() {
        return mWatchNextType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_POSTER_ART_ASPECT_RATIO} for the program.
     */
    public @AspectRatio String getPosterArtAspectRatio() {
        return mPosterArtAspectRatio;
    }

    /**
     * @return The value of {@link Programs#COLUMN_THUMBNAIL_ASPECT_RATIO} for the program.
     */
    public @AspectRatio String getThumbnailAspectRatio() {
        return mThumbnailAspectRatio;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LOGO_URI} for the program.
     */
    public Uri getLogoUri() {
        return mLogoUri;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AVAILABILITY} for the program.
     */
    public @Availability String getAvailability() {
        return mAvailability;
    }

    /**
     * @return The value of {@link Programs#COLUMN_STARTING_PRICE} for the program.
     */
    public String getStartingPrice() {
        return mStartingPrice;
    }

    /**
     * @return The value of {@link Programs#COLUMN_OFFER_PRICE} for the program.
     */
    public String getOfferPrice() {
        return mOfferPrice;
    }

    /**
     * @return The value of {@link Programs#COLUMN_RELEASE_DATE} for the program.
     */
    public String getReleaseDate() {
        return mReleaseDate;
    }

    /**
     * @return The value of {@link Programs#COLUMN_ITEM_COUNT} for the program.
     */
    public int getItemCount() {
        return mItemCount;
    }

    /**
     * @return The value of {@link Programs#COLUMN_LIVE} for the program.
     */
    public boolean isLive() {
        return mLive == IS_LIVE;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERACTION_TYPE} for the program.
     */
    public @InteractionType String getInteractionType() {
        return mInteractionType;
    }

    /**
     * @return The value of {@link Programs#COLUMN_INTERACTION_COUNT} for the program.
     */
    public int getInteractionCount() {
        return mInteractionCount;
    }

    /**
     * @return The value of {@link Programs#COLUMN_AUTHOR} for the program.
     */
    public String getAuthor() {
        return mAuthor;
    }

    /**
     * @return The value of {@link Programs#COLUMN_REVIEW_RATING_STYLE} for the program.
     */
    public @ReviewRatingStyle String getReviewRatingStyle() {
        return mReviewRatingStyle;
    }

    /**
     * @return The value of {@link Programs#COLUMN_REVIEW_RATING} for the program.
     */
    public String getReviewRating() {
        return mReviewRating;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis,
                mTitle, mEpisodeTitle, mDescription, mLongDescription, mVideoWidth, mVideoHeight,
                mPosterArtUri, mThumbnailUri, Arrays.hashCode(mContentRatings),
                Arrays.hashCode(mCanonicalGenres), mSeasonNumber, mEpisodeNumber);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Program)) {
            return false;
        }
        Program program = (Program) other;
        return mChannelId == program.mChannelId
                && mStartTimeUtcMillis == program.mStartTimeUtcMillis
                && mEndTimeUtcMillis == program.mEndTimeUtcMillis
                && Objects.equals(mTitle, program.mTitle)
                && Objects.equals(mEpisodeTitle, program.mEpisodeTitle)
                && Objects.equals(mSeasonNumber, program.mSeasonNumber)
                && Objects.equals(mEpisodeNumber, program.mEpisodeNumber)
                && Objects.equals(mDescription, program.mDescription)
                && Objects.equals(mLongDescription, program.mLongDescription)
                && mVideoWidth == program.mVideoWidth
                && mVideoHeight == program.mVideoHeight
                && Objects.equals(mPosterArtUri, program.mPosterArtUri)
                && Objects.equals(mThumbnailUri, program.mThumbnailUri)
{'fraction_non_alphanumeric': 0.08151087763375778, 'fraction_numerical': 0.002226917147262034, 'mean_word_length': 2.8750968027436663, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7387279', 'n_tokens_mistral': 10332, 'n_tokens_neox': 10068, 'n_words': 2559}