/*
 * Copyright 2018 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.media;

import static androidx.media.AudioAttributesCompat.CONTENT_TYPE_UNKNOWN;
import static androidx.media.AudioAttributesCompat.USAGE_UNKNOWN;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_DESCRIPTION;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON_URI;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_SUBTITLE;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_TITLE;
import static androidx.media.MediaMetadata2.METADATA_KEY_EXTRAS;
import static androidx.media.MediaMetadata2.METADATA_KEY_MEDIA_ID;
import static androidx.media.MediaMetadata2.METADATA_KEY_MEDIA_URI;
import static androidx.media.MediaMetadata2.METADATA_KEY_TITLE;

import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.RatingCompat;
import android.support.v4.media.session.PlaybackStateCompat;

import androidx.media.MediaSession2.CommandButton;

import java.util.ArrayList;
import java.util.List;

class MediaUtils2 {
    static final String AUDIO_ATTRIBUTES_USAGE = "androidx.media.audio_attrs.USAGE";
    static final String AUDIO_ATTRIBUTES_CONTENT_TYPE = "androidx.media.audio_attrs.CONTENT_TYPE";
    static final String AUDIO_ATTRIBUTES_FLAGS = "androidx.media.audio_attrs.FLAGS";

    private MediaUtils2() {
    }

    /**
     * Creates a {@link MediaItem} from the {@link MediaItem2}.
     *
     * @param item2 an item.
     * @return The newly created media item.
     */
    static MediaItem createMediaItem(MediaItem2 item2) {
        if (item2 == null) {
            return null;
        }
        MediaDescriptionCompat descCompat;

        MediaMetadata2 metadata = item2.getMetadata();
        if (metadata == null) {
            descCompat = new MediaDescriptionCompat.Builder()
                    .setMediaId(item2.getMediaId())
                    .build();
        } else {
            MediaDescriptionCompat.Builder builder = new MediaDescriptionCompat.Builder()
                    .setMediaId(item2.getMediaId())
                    .setSubtitle(metadata.getText(METADATA_KEY_DISPLAY_SUBTITLE))
                    .setDescription(metadata.getText(METADATA_KEY_DISPLAY_DESCRIPTION))
                    .setIconBitmap(metadata.getBitmap(METADATA_KEY_DISPLAY_ICON))
                    .setExtras(metadata.getExtras());

            String title = metadata.getString(METADATA_KEY_TITLE);
            if (title != null) {
                builder.setTitle(title);
            } else {
                builder.setTitle(metadata.getString(METADATA_KEY_DISPLAY_TITLE));
            }

            String displayIconUri = metadata.getString(METADATA_KEY_DISPLAY_ICON_URI);
            if (displayIconUri != null) {
                builder.setIconUri(Uri.parse(displayIconUri));
            }

            String mediaUri = metadata.getString(METADATA_KEY_MEDIA_URI);
            if (mediaUri != null) {
                builder.setMediaUri(Uri.parse(mediaUri));
            }

            descCompat = builder.build();
        }
        return new MediaItem(descCompat, item2.getFlags());
    }

    /**
     * Creates a {@link MediaItem2} from the {@link MediaItem}.
     *
     * @param item an item.
     * @return The newly created media item.
     */
    static MediaItem2 createMediaItem2(MediaItem item) {
        if (item == null || item.getMediaId() == null) {
            return null;
        }

        MediaMetadata2 metadata2 = createMediaMetadata2(item.getDescription());
        return new MediaItem2.Builder(item.getFlags())
                .setMediaId(item.getMediaId())
                .setMetadata(metadata2)
                .build();
    }

    /**
     * Creates a {@link MediaMetadata2} from the {@link MediaDescriptionCompat}.
     *
     * @param descCompat A {@link MediaDescriptionCompat} object.
     * @return The newly created {@link MediaMetadata2} object.
     */
    static MediaMetadata2 createMediaMetadata2(MediaDescriptionCompat descCompat) {
        if (descCompat == null) {
            return null;
        }

        MediaMetadata2.Builder metadata2Builder = new MediaMetadata2.Builder();
        metadata2Builder.putString(METADATA_KEY_MEDIA_ID, descCompat.getMediaId());

        CharSequence title = descCompat.getTitle();
        if (title != null) {
            metadata2Builder.putText(METADATA_KEY_DISPLAY_TITLE, title);
        }

        CharSequence description = descCompat.getDescription();
        if (description != null) {
            metadata2Builder.putText(METADATA_KEY_DISPLAY_DESCRIPTION, descCompat.getDescription());
        }

        CharSequence subtitle = descCompat.getSubtitle();
        if (subtitle != null) {
            metadata2Builder.putText(METADATA_KEY_DISPLAY_SUBTITLE, subtitle);
        }

        Bitmap icon = descCompat.getIconBitmap();
        if (icon != null) {
            metadata2Builder.putBitmap(METADATA_KEY_DISPLAY_ICON, icon);
        }

        Uri iconUri = descCompat.getIconUri();
        if (iconUri != null) {
            metadata2Builder.putText(METADATA_KEY_DISPLAY_ICON_URI, iconUri.toString());
        }

        Bundle bundle = descCompat.getExtras();
        if (bundle != null) {
            metadata2Builder.setExtras(descCompat.getExtras());
        }

        Uri mediaUri = descCompat.getMediaUri();
        if (mediaUri != null) {
            metadata2Builder.putText(METADATA_KEY_MEDIA_URI, mediaUri.toString());
        }

        return metadata2Builder.build();
    }

    /**
     * Creates a {@link MediaMetadata2} from the {@link MediaMetadataCompat}.
     *
     * @param metadataCompat A {@link MediaMetadataCompat} object.
     * @return The newly created {@link MediaMetadata2} object.
     */
    MediaMetadata2 createMediaMetadata2(MediaMetadataCompat metadataCompat) {
        if (metadataCompat == null) {
            return null;
        }
        return new MediaMetadata2(metadataCompat.getBundle());
    }

    /**
     * Creates a {@link MediaMetadataCompat} from the {@link MediaMetadata2}.
     *
     * @param metadata2 A {@link MediaMetadata2} object.
     * @return The newly created {@link MediaMetadataCompat} object.
     */
    MediaMetadataCompat createMediaMetadataCompat(MediaMetadata2 metadata2) {
        if (metadata2 == null) {
            return null;
        }

        MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();

        List<String> skippedKeys = new ArrayList<>();
        Bundle bundle = metadata2.toBundle();
        for (String key : bundle.keySet()) {
            Object value = bundle.get(key);
            if (value instanceof CharSequence) {
                builder.putText(key, (CharSequence) value);
            } else if (value instanceof Rating2) {
                builder.putRating(key, createRatingCompat((Rating2) value));
            } else if (value instanceof Bitmap) {
                builder.putBitmap(key, (Bitmap) value);
            } else if (value instanceof Long) {
                builder.putLong(key, (Long) value);
            } else {
                // There is no 'float' or 'bundle' type in MediaMetadataCompat.
                skippedKeys.add(key);
            }
        }

        MediaMetadataCompat result = builder.build();
        for (String key : skippedKeys) {
            Object value = bundle.get(key);
            if (value instanceof Float) {
                // Compatibility for MediaMetadata2.Builder.putFloat()
                result.getBundle().putFloat(key, (Float) value);
            } else if (METADATA_KEY_EXTRAS.equals(value)) {
                // Compatibility for MediaMetadata2.Builder.setExtras()
                result.getBundle().putBundle(key, (Bundle) value);
            }
        }
        return result;
    }

    /**
     * Creates a {@link Rating2} from the {@link RatingCompat}.
     *
     * @param ratingCompat A {@link RatingCompat} object.
     * @return The newly created {@link Rating2} object.
     */
    Rating2 createRating2(RatingCompat ratingCompat) {
        if (ratingCompat == null) {
            return null;
        }
        if (!ratingCompat.isRated()) {
            return Rating2.newUnratedRating(ratingCompat.getRatingStyle());
        }

        switch (ratingCompat.getRatingStyle()) {
            case RatingCompat.RATING_3_STARS:
            case RatingCompat.RATING_4_STARS:
            case RatingCompat.RATING_5_STARS:
                return Rating2.newStarRating(
                        ratingCompat.getRatingStyle(), ratingCompat.getStarRating());
            case RatingCompat.RATING_HEART:
                return Rating2.newHeartRating(ratingCompat.hasHeart());
            case RatingCompat.RATING_THUMB_UP_DOWN:
                return Rating2.newThumbRating(ratingCompat.isThumbUp());
            case RatingCompat.RATING_PERCENTAGE:
                return Rating2.newPercentageRating(ratingCompat.getPercentRating());
            default:
                return null;
        }
    }

    /**
     * Creates a {@link RatingCompat} from the {@link Rating2}.
     *
     * @param rating2 A {@link Rating2} object.
     * @return The newly created {@link RatingCompat} object.
     */
    RatingCompat createRatingCompat(Rating2 rating2) {
        if (rating2 == null) {
            return null;
        }
        if (!rating2.isRated()) {
            return RatingCompat.newUnratedRating(rating2.getRatingStyle());
        }

        switch (rating2.getRatingStyle()) {
            case Rating2.RATING_3_STARS:
            case Rating2.RATING_4_STARS:
            case Rating2.RATING_5_STARS:
                return RatingCompat.newStarRating(
                        rating2.getRatingStyle(), rating2.getStarRating());
            case Rating2.RATING_HEART:
                return RatingCompat.newHeartRating(rating2.hasHeart());
            case Rating2.RATING_THUMB_UP_DOWN:
                return RatingCompat.newThumbRating(rating2.isThumbUp());
            case Rating2.RATING_PERCENTAGE:
                return RatingCompat.newPercentageRating(rating2.getPercentRating());
            default:
                return null;
        }
    }

    static Parcelable[] toMediaItem2ParcelableArray(List<MediaItem2> playlist) {
        if (playlist == null) {
            return null;
        }
        List<Parcelable> parcelableList = new ArrayList<>();
        for (int i = 0; i < playlist.size(); i++) {
            final MediaItem2 item = playlist.get(i);
            if (item != null) {
                final Parcelable itemBundle = item.toBundle();
                if (itemBundle != null) {
                    parcelableList.add(itemBundle);
                }
            }
        }
        return parcelableList.toArray(new Parcelable[0]);
    }

    static List<MediaItem2> fromMediaItem2ParcelableArray(Parcelable[] itemParcelableList) {
        List<MediaItem2> playlist = new ArrayList<>();
        if (itemParcelableList != null) {
            for (int i = 0; i < itemParcelableList.length; i++) {
                if (!(itemParcelableList[i] instanceof Bundle)) {
                    continue;
                }
                MediaItem2 item = MediaItem2.fromBundle((Bundle) itemParcelableList[i]);
                if (item != null) {
                    playlist.add(item);
                }
            }
        }
        return playlist;
    }

    static Parcelable[] toCommandButtonParcelableArray(List<CommandButton> layout) {
        if (layout == null) {
            return null;
        }
        List<Bundle> layoutBundles = new ArrayList<>();
        for (int i = 0; i < layout.size(); i++) {
            Bundle bundle = layout.get(i).toBundle();
            if (bundle != null) {
                layoutBundles.add(bundle);
            }
        }
        return layoutBundles.toArray(new Parcelable[0]);
    }

    static List<CommandButton> fromCommandButtonParcelableArray(Parcelable[] list) {
        List<CommandButton> layout = new ArrayList<>();
        if (layout != null) {
            for (int i = 0; i < list.length; i++) {
                if (!(list[i] instanceof Bundle)) {
                    continue;
                }
                CommandButton button = CommandButton.fromBundle((Bundle) list[i]);
                if (button != null) {
                    layout.add(button);
                }
            }
        }
        return layout;
    }

    static Bundle toAudioAttributesBundle(AudioAttributesCompat attrs) {
        if (attrs == null) {
            return null;
        }
        Bundle bundle = new Bundle();
        bundle.putInt(AUDIO_ATTRIBUTES_USAGE, attrs.getUsage());
        bundle.putInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, attrs.getContentType());
        bundle.putInt(AUDIO_ATTRIBUTES_FLAGS, attrs.getFlags());
        return bundle;
    }

    static AudioAttributesCompat fromAudioAttributesBundle(Bundle bundle) {
        if (bundle == null) {
            return null;
        }
        return new AudioAttributesCompat.Builder()
                .setUsage(bundle.getInt(AUDIO_ATTRIBUTES_USAGE, USAGE_UNKNOWN))
                .setContentType(bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, CONTENT_TYPE_UNKNOWN))
                .setFlags(bundle.getInt(AUDIO_ATTRIBUTES_FLAGS, 0))
                .build();
    }

    static List<Bundle> toBundleList(Parcelable[] array) {
        if (array == null) {
            return null;
        }
        List<Bundle> bundleList = new ArrayList<>();
        for (Parcelable p : array) {
            bundleList.add((Bundle) p);
        }
        return bundleList;
    }

    static int createPlaybackStateCompatState(int playerState, int bufferingState) {
        switch (playerState) {
            case MediaPlayerBase.PLAYER_STATE_PLAYING:
                switch (bufferingState) {
                    case MediaPlayerBase.BUFFERING_STATE_BUFFERING_AND_STARVED:
                        return PlaybackStateCompat.STATE_BUFFERING;
                }
                return PlaybackStateCompat.STATE_PLAYING;
            case MediaPlayerBase.PLAYER_STATE_PAUSED:
                return PlaybackStateCompat.STATE_PAUSED;
            case MediaPlayerBase.PLAYER_STATE_IDLE:
                return PlaybackStateCompat.STATE_NONE;
            case MediaPlayerBase.PLAYER_STATE_ERROR:
                return PlaybackStateCompat.STATE_ERROR;
        }
        // For unknown value
        return PlaybackStateCompat.STATE_ERROR;
    }

    static int toPlayerState(int playbackStateCompatState) {
        switch (playbackStateCompatState) {
            case PlaybackStateCompat.STATE_ERROR:
                return MediaPlayerBase.PLAYER_STATE_ERROR;
            case PlaybackStateCompat.STATE_NONE:
                return MediaPlayerBase.PLAYER_STATE_IDLE;
            case PlaybackStateCompat.STATE_PAUSED:
            case PlaybackStateCompat.STATE_STOPPED:
            case PlaybackStateCompat.STATE_BUFFERING: // means paused for buffering.
                return MediaPlayerBase.PLAYER_STATE_PAUSED;
            case PlaybackStateCompat.STATE_FAST_FORWARDING:
            case PlaybackStateCompat.STATE_PLAYING:
            case PlaybackStateCompat.STATE_REWINDING:
            case PlaybackStateCompat.STATE_SKIPPING_TO_NEXT:
            case PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS:
            case PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM:
            case PlaybackStateCompat.STATE_CONNECTING: // Note: there's no perfect match for this.
                return MediaPlayerBase.PLAYER_STATE_PLAYING;
        }
        return MediaPlayerBase.PLAYER_STATE_ERROR;
    }

    static boolean isDefaultLibraryRootHint(Bundle bundle) {
        return bundle != null && bundle.getBoolean(MediaConstants2.ROOT_EXTRA_DEFAULT, false);
    }
}
