/*
 * Copyright 2019 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 androidx.media2.player;

import static android.media.MediaFormat.MIMETYPE_TEXT_CEA_608;
import static android.media.MediaFormat.MIMETYPE_TEXT_CEA_708;

import static androidx.media2.common.SessionPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO;
import static androidx.media2.common.SessionPlayer.TrackInfo.MEDIA_TRACK_TYPE_METADATA;
import static androidx.media2.common.SessionPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
import static androidx.media2.common.SessionPlayer.TrackInfo.MEDIA_TRACK_TYPE_UNKNOWN;
import static androidx.media2.common.SessionPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO;
import static androidx.media2.player.MediaPlayer2.MEDIA_ERROR_IO;
import static androidx.media2.player.MediaPlayer2.MEDIA_ERROR_MALFORMED;
import static androidx.media2.player.MediaPlayer2.MEDIA_ERROR_TIMED_OUT;
import static androidx.media2.player.MediaPlayer2.MEDIA_ERROR_UNKNOWN;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.media.MediaFormat;
import android.net.Uri;

import androidx.core.util.Preconditions;
import androidx.media.AudioAttributesCompat;
import androidx.media2.common.CallbackMediaItem;
import androidx.media2.common.FileMediaItem;
import androidx.media2.common.MediaItem;
import androidx.media2.common.UriMediaItem;
import androidx.media2.exoplayer.external.C;
import androidx.media2.exoplayer.external.ExoPlaybackException;
import androidx.media2.exoplayer.external.Format;
import androidx.media2.exoplayer.external.ParserException;
import androidx.media2.exoplayer.external.PlaybackParameters;
import androidx.media2.exoplayer.external.SeekParameters;
import androidx.media2.exoplayer.external.audio.AudioAttributes;
import androidx.media2.exoplayer.external.extractor.DefaultExtractorsFactory;
import androidx.media2.exoplayer.external.extractor.ExtractorsFactory;
import androidx.media2.exoplayer.external.extractor.ts.AdtsExtractor;
import androidx.media2.exoplayer.external.mediacodec.MediaFormatUtil;
import androidx.media2.exoplayer.external.source.ExtractorMediaSource;
import androidx.media2.exoplayer.external.source.MediaSource;
import androidx.media2.exoplayer.external.source.hls.HlsMediaSource;
import androidx.media2.exoplayer.external.upstream.DataSource;
import androidx.media2.exoplayer.external.upstream.HttpDataSource;
import androidx.media2.exoplayer.external.upstream.RawResourceDataSource;
import androidx.media2.exoplayer.external.util.MimeTypes;
import androidx.media2.exoplayer.external.util.Util;

import java.io.IOException;
import java.net.SocketTimeoutException;

/**
 * Utility methods for translating between the MediaPlayer2 and ExoPlayer APIs.
 */
@SuppressLint("RestrictedApi") // TODO(b/68398926): Remove once RestrictedApi checks are fixed.
/* package */ class ExoPlayerUtils {

    private static final ExtractorsFactory sExtractorsFactory = new DefaultExtractorsFactory()
            .setAdtsExtractorFlags(AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING);

    /**
     * Returns an ExoPlayer media source for the given media item. The given {@link MediaItem} is
     * set as the tag of the source.
     */
    public static MediaSource createUnclippedMediaSource(
            Context context, DataSource.Factory dataSourceFactory, MediaItem mediaItem) {
        if (mediaItem instanceof UriMediaItem) {
            Uri uri = ((UriMediaItem) mediaItem).getUri();
            if (Util.inferContentType(uri) == C.TYPE_HLS) {
                return new HlsMediaSource.Factory(dataSourceFactory)
                        .setTag(mediaItem)
                        .createMediaSource(uri);
            } else {
                if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
                    String path = Preconditions.checkNotNull(uri.getPath());
                    int resourceIdentifier;
                    if (uri.getPathSegments().size() == 1
                            && uri.getPathSegments().get(0).matches("\\d+")) {
                        resourceIdentifier = Integer.parseInt(uri.getPathSegments().get(0));
                    } else {
                        path = path.replaceAll("^/", "");
                        String host = uri.getHost();
                        String resourceName = (host != null ? host + ":" : "") + path;
                        resourceIdentifier = context.getResources()
                                .getIdentifier(resourceName, "raw", context.getPackageName());
                    }
                    Preconditions.checkState(resourceIdentifier != 0);
                    uri = RawResourceDataSource.buildRawResourceUri(resourceIdentifier);
                }
                return new ExtractorMediaSource.Factory(dataSourceFactory)
                        .setExtractorsFactory(sExtractorsFactory)
                        .setTag(mediaItem)
                        .createMediaSource(uri);
            }
        } else if (mediaItem instanceof FileMediaItem) {
            return new ExtractorMediaSource.Factory(dataSourceFactory)
                    .setExtractorsFactory(sExtractorsFactory)
                    .setTag(mediaItem)
                    .createMediaSource(Uri.EMPTY);
        } else if (mediaItem instanceof CallbackMediaItem) {
            CallbackMediaItem callbackMediaItem = (CallbackMediaItem) mediaItem;
            dataSourceFactory = DataSourceCallbackDataSource.getFactory(
                    callbackMediaItem.getDataSourceCallback());
            return new ExtractorMediaSource.Factory(dataSourceFactory)
                    .setExtractorsFactory(sExtractorsFactory)
                    .setTag(mediaItem)
                    .createMediaSource(Uri.EMPTY);
        } else {
            throw new IllegalStateException();
        }
    }

    /** Returns ExoPlayer audio attributes for the given audio attributes. */
    public static AudioAttributes getAudioAttributes(AudioAttributesCompat audioAttributesCompat) {
        return new AudioAttributes.Builder()
                .setContentType(audioAttributesCompat.getContentType())
                .setFlags(audioAttributesCompat.getFlags())
                .setUsage(audioAttributesCompat.getUsage())
                .build();
    }

    /** Returns audio attributes for the given ExoPlayer audio attributes. */
    public static AudioAttributesCompat getAudioAttributesCompat(AudioAttributes audioAttributes) {
        return new AudioAttributesCompat.Builder()
                .setContentType(audioAttributes.contentType)
                .setFlags(audioAttributes.flags)
                .setUsage(audioAttributes.usage)
                .build();
    }

    /** Returns ExoPlayer playback parameters for the given playback params. */
    public static PlaybackParameters getPlaybackParameters(PlaybackParams playbackParams2) {
        Float speed = playbackParams2.getSpeed();
        Float pitch = playbackParams2.getPitch();
        return new PlaybackParameters(speed != null ? speed : 1f, pitch != null ? pitch : 1f);
    }

    /** Returns the ExoPlayer seek parameters corresponding to the given seek mode. */
    public static SeekParameters getSeekParameters(int seekMode) {
        switch (seekMode) {
            case MediaPlayer2.SEEK_CLOSEST:
                return SeekParameters.EXACT;
            case MediaPlayer2.SEEK_CLOSEST_SYNC:
                return SeekParameters.CLOSEST_SYNC;
            case MediaPlayer2.SEEK_NEXT_SYNC:
                return SeekParameters.NEXT_SYNC;
            case MediaPlayer2.SEEK_PREVIOUS_SYNC:
                return SeekParameters.PREVIOUS_SYNC;
            default:
                throw new IllegalArgumentException();
        }
    }

    /** Returns the MEDIA_ERROR_* constant for an ExoPlayer player exception. */
    public static int getError(ExoPlaybackException exception) {
        if (exception.type == ExoPlaybackException.TYPE_SOURCE) {
            IOException sourceException = exception.getSourceException();
            if (sourceException instanceof ParserException) {
                return MEDIA_ERROR_MALFORMED;
            } else {
                if (sourceException instanceof HttpDataSource.HttpDataSourceException
                        && sourceException.getCause() instanceof SocketTimeoutException) {
                    return MEDIA_ERROR_TIMED_OUT;
                }
                return MEDIA_ERROR_IO;
            }
        }
        return MEDIA_ERROR_UNKNOWN;
    }

    /** Returns the ExoPlayer track type for the given track type. */
    public static int getExoPlayerTrackType(int trackType) {
        switch (trackType) {
            case MEDIA_TRACK_TYPE_AUDIO:
                return C.TRACK_TYPE_AUDIO;
            case MEDIA_TRACK_TYPE_VIDEO:
                return C.TRACK_TYPE_VIDEO;
            case MEDIA_TRACK_TYPE_SUBTITLE:
                return C.TRACK_TYPE_TEXT;
            case MEDIA_TRACK_TYPE_METADATA:
                return C.TRACK_TYPE_METADATA;
            case MEDIA_TRACK_TYPE_UNKNOWN:
            default:
                return C.TRACK_TYPE_UNKNOWN;
        }
    }

    /** Returns the track type corresponding to the given ExoPlayer track type. */
    public static int getTrackType(int exoPlayerTrackType) {
        switch (exoPlayerTrackType) {
            case C.TRACK_TYPE_AUDIO:
                return MEDIA_TRACK_TYPE_AUDIO;
            case C.TRACK_TYPE_VIDEO:
                return MEDIA_TRACK_TYPE_VIDEO;
            case C.TRACK_TYPE_TEXT:
                return MEDIA_TRACK_TYPE_SUBTITLE;
            case C.TRACK_TYPE_METADATA:
                return MEDIA_TRACK_TYPE_METADATA;
            case C.TRACK_TYPE_NONE:
            case C.TRACK_TYPE_CAMERA_MOTION:
            case C.TRACK_TYPE_DEFAULT:
            case C.TRACK_TYPE_UNKNOWN:
            default:
                return MEDIA_TRACK_TYPE_UNKNOWN;
        }
    }

    /** Returns the media format corresponding to an ExoPlayer format. */
    @SuppressLint("InlinedApi")
    public static MediaFormat getMediaFormat(Format format) {
        MediaFormat mediaFormat = new MediaFormat();
        String mimeType = format.sampleMimeType;
        mediaFormat.setString(MediaFormat.KEY_MIME, mimeType);
        int trackType = MimeTypes.getTrackType(mimeType);
        if (trackType == C.TRACK_TYPE_AUDIO) {
            mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, format.channelCount);
            mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, format.sampleRate);
            if (format.language != null) {
                mediaFormat.setString(MediaFormat.KEY_LANGUAGE, format.language);
            }
        } else if (trackType == C.TRACK_TYPE_VIDEO) {
            MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_WIDTH, format.width);
            MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_HEIGHT, format.height);
            MediaFormatUtil.maybeSetFloat(
                    mediaFormat, MediaFormat.KEY_FRAME_RATE, format.frameRate);
            MediaFormatUtil.maybeSetInteger(
                    mediaFormat, MediaFormat.KEY_ROTATION, format.rotationDegrees);
            MediaFormatUtil.maybeSetColorInfo(mediaFormat, format.colorInfo);
        } else if (trackType == C.TRACK_TYPE_TEXT) {
            boolean isAutoselect = format.selectionFlags == C.SELECTION_FLAG_AUTOSELECT;
            boolean isDefault = format.selectionFlags == C.SELECTION_FLAG_DEFAULT;
            boolean isForced = format.selectionFlags == C.SELECTION_FLAG_FORCED;
            mediaFormat.setInteger(MediaFormat.KEY_IS_AUTOSELECT, isAutoselect ? 1 : 0);
            mediaFormat.setInteger(MediaFormat.KEY_IS_DEFAULT, isDefault ? 1 : 0);
            mediaFormat.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, isForced ? 1 : 0);
            if (format.language == null) {
                mediaFormat.setString(MediaFormat.KEY_LANGUAGE, C.LANGUAGE_UNDETERMINED);
            } else {
                mediaFormat.setString(MediaFormat.KEY_LANGUAGE, format.language);
            }
            // MediaPlayer2 uses text/* instead of application/* MIME types.
            if (MimeTypes.APPLICATION_CEA608.equals(mimeType)) {
                mediaFormat.setString(MediaFormat.KEY_MIME, MIMETYPE_TEXT_CEA_608);
            } else if (MimeTypes.APPLICATION_CEA708.equals(mimeType)) {
                mediaFormat.setString(MediaFormat.KEY_MIME, MIMETYPE_TEXT_CEA_708);
            }
        }
        return mediaFormat;
    }

    private ExoPlayerUtils() {
        // Prevent instantiation.
    }

}
