/*
 * 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 android.hardware.radio;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;

import java.util.Set;

/**
 * Contains meta data about a radio program such as station name, song title, artist etc...
 * @hide
 */
@SystemApi
public final class RadioMetadata implements Parcelable {
    private static final String TAG = "BroadcastRadio.metadata";

    /**
     * The RDS Program Information.
     */
    public static final String METADATA_KEY_RDS_PI = "android.hardware.radio.metadata.RDS_PI";

    /**
     * The RDS Program Service.
     */
    public static final String METADATA_KEY_RDS_PS = "android.hardware.radio.metadata.RDS_PS";

    /**
     * The RDS PTY.
     */
    public static final String METADATA_KEY_RDS_PTY = "android.hardware.radio.metadata.RDS_PTY";

    /**
     * The RBDS PTY.
     */
    public static final String METADATA_KEY_RBDS_PTY = "android.hardware.radio.metadata.RBDS_PTY";

    /**
     * The RBDS Radio Text.
     */
    public static final String METADATA_KEY_RDS_RT = "android.hardware.radio.metadata.RDS_RT";

    /**
     * The song title.
     */
    public static final String METADATA_KEY_TITLE = "android.hardware.radio.metadata.TITLE";

    /**
     * The artist name.
     */
    public static final String METADATA_KEY_ARTIST = "android.hardware.radio.metadata.ARTIST";

    /**
     * The album name.
     */
    public static final String METADATA_KEY_ALBUM = "android.hardware.radio.metadata.ALBUM";

    /**
     * The music genre.
     */
    public static final String METADATA_KEY_GENRE = "android.hardware.radio.metadata.GENRE";

    /**
     * The radio station icon {@link Bitmap}.
     */
    public static final String METADATA_KEY_ICON = "android.hardware.radio.metadata.ICON";

    /**
     * The artwork for the song/album {@link Bitmap}.
     */
    public static final String METADATA_KEY_ART = "android.hardware.radio.metadata.ART";

    /**
     * The clock.
     */
    public static final String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK";

    /**
     * Technology-independent program name (station name).
     */
    public static final String METADATA_KEY_PROGRAM_NAME =
            "android.hardware.radio.metadata.PROGRAM_NAME";

    /**
     * DAB ensemble name.
     */
    public static final String METADATA_KEY_DAB_ENSEMBLE_NAME =
            "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME";

    /**
     * DAB ensemble name - short version (up to 8 characters).
     */
    public static final String METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT =
            "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME_SHORT";

    /**
     * DAB service name.
     */
    public static final String METADATA_KEY_DAB_SERVICE_NAME =
            "android.hardware.radio.metadata.DAB_SERVICE_NAME";

    /**
     * DAB service name - short version (up to 8 characters).
     */
    public static final String METADATA_KEY_DAB_SERVICE_NAME_SHORT =
            "android.hardware.radio.metadata.DAB_SERVICE_NAME_SHORT";

    /**
     * DAB component name.
     */
    public static final String METADATA_KEY_DAB_COMPONENT_NAME =
            "android.hardware.radio.metadata.DAB_COMPONENT_NAME";

    /**
     * DAB component name.
     */
    public static final String METADATA_KEY_DAB_COMPONENT_NAME_SHORT =
            "android.hardware.radio.metadata.DAB_COMPONENT_NAME_SHORT";


    private static final int METADATA_TYPE_INVALID = -1;
    private static final int METADATA_TYPE_INT = 0;
    private static final int METADATA_TYPE_TEXT = 1;
    private static final int METADATA_TYPE_BITMAP = 2;
    private static final int METADATA_TYPE_CLOCK = 3;

    private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;

    static {
        METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
        METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PI, METADATA_TYPE_INT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PS, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PTY, METADATA_TYPE_INT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_RBDS_PTY, METADATA_TYPE_INT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_RT, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_ICON, METADATA_TYPE_BITMAP);
        METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
        METADATA_KEYS_TYPE.put(METADATA_KEY_CLOCK, METADATA_TYPE_CLOCK);
        METADATA_KEYS_TYPE.put(METADATA_KEY_PROGRAM_NAME, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME_SHORT, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME, METADATA_TYPE_TEXT);
        METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME_SHORT, METADATA_TYPE_TEXT);
    }

    // keep in sync with: system/media/radio/include/system/radio_metadata.h
    private static final int NATIVE_KEY_INVALID     = -1;
    private static final int NATIVE_KEY_RDS_PI      = 0;
    private static final int NATIVE_KEY_RDS_PS      = 1;
    private static final int NATIVE_KEY_RDS_PTY     = 2;
    private static final int NATIVE_KEY_RBDS_PTY    = 3;
    private static final int NATIVE_KEY_RDS_RT      = 4;
    private static final int NATIVE_KEY_TITLE       = 5;
    private static final int NATIVE_KEY_ARTIST      = 6;
    private static final int NATIVE_KEY_ALBUM       = 7;
    private static final int NATIVE_KEY_GENRE       = 8;
    private static final int NATIVE_KEY_ICON        = 9;
    private static final int NATIVE_KEY_ART         = 10;
    private static final int NATIVE_KEY_CLOCK       = 11;

    private static final SparseArray<String> NATIVE_KEY_MAPPING;

    static {
        NATIVE_KEY_MAPPING = new SparseArray<String>();
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PI, METADATA_KEY_RDS_PI);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PS, METADATA_KEY_RDS_PS);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PTY, METADATA_KEY_RDS_PTY);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_RBDS_PTY, METADATA_KEY_RBDS_PTY);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_RT, METADATA_KEY_RDS_RT);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_TITLE, METADATA_KEY_TITLE);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_ARTIST, METADATA_KEY_ARTIST);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_ALBUM, METADATA_KEY_ALBUM);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_GENRE, METADATA_KEY_GENRE);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_ICON, METADATA_KEY_ICON);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_ART, METADATA_KEY_ART);
        NATIVE_KEY_MAPPING.put(NATIVE_KEY_CLOCK, METADATA_KEY_CLOCK);
    }

    /**
     * Provides a Clock that can be used to describe time as provided by the Radio.
     *
     * The clock is defined by the seconds since epoch at the UTC + 0 timezone
     * and timezone offset from UTC + 0 represented in number of minutes.
     *
     * @hide
     */
    @SystemApi
    public static final class Clock implements Parcelable {
        private final long mUtcEpochSeconds;
        private final int mTimezoneOffsetMinutes;

        public int describeContents() {
            return 0;
        }

        public void writeToParcel(Parcel out, int flags) {
            out.writeLong(mUtcEpochSeconds);
            out.writeInt(mTimezoneOffsetMinutes);
        }

        public static final @android.annotation.NonNull Parcelable.Creator<Clock> CREATOR
                = new Parcelable.Creator<Clock>() {
            public Clock createFromParcel(Parcel in) {
                return new Clock(in);
            }

            public Clock[] newArray(int size) {
                return new Clock[size];
            }
        };

        public Clock(long utcEpochSeconds, int timezoneOffsetMinutes) {
            mUtcEpochSeconds = utcEpochSeconds;
            mTimezoneOffsetMinutes = timezoneOffsetMinutes;
        }

        private Clock(Parcel in) {
            mUtcEpochSeconds = in.readLong();
            mTimezoneOffsetMinutes = in.readInt();
        }

        public long getUtcEpochSeconds() {
            return mUtcEpochSeconds;
        }

        public int getTimezoneOffsetMinutes() {
            return mTimezoneOffsetMinutes;
        }
    }

    private final Bundle mBundle;

    RadioMetadata() {
        mBundle = new Bundle();
    }

    private RadioMetadata(Bundle bundle) {
        mBundle = new Bundle(bundle);
    }

    private RadioMetadata(Parcel in) {
        mBundle = in.readBundle();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("RadioMetadata[");

        final String removePrefix = "android.hardware.radio.metadata";

        boolean first = true;
        for (String key : mBundle.keySet()) {
            if (first) first = false;
            else sb.append(", ");

            String keyDisp = key;
            if (key.startsWith(removePrefix)) keyDisp = key.substring(removePrefix.length());

            sb.append(keyDisp);
            sb.append('=');
            sb.append(mBundle.get(key));
        }

        sb.append("]");
        return sb.toString();
    }

    /**
     * Returns {@code true} if the given key is contained in the meta data
     *
     * @param key a String key
     * @return {@code true} if the key exists in this meta data, {@code false} otherwise
     */
    public boolean containsKey(String key) {
        return mBundle.containsKey(key);
    }

    /**
     * Returns the text value associated with the given key as a String, or null
     * if the key is not found in the meta data.
     *
     * @param key The key the value is stored under
     * @return a String value, or null
     */
    public String getString(String key) {
        return mBundle.getString(key);
    }

    private static void putInt(Bundle bundle, String key, int value) {
        int type = METADATA_KEYS_TYPE.getOrDefault(key, METADATA_TYPE_INVALID);
        if (type != METADATA_TYPE_INT && type != METADATA_TYPE_BITMAP) {
            throw new IllegalArgumentException("The " + key + " key cannot be used to put an int");
        }
        bundle.putInt(key, value);
    }

    /**
     * Returns the value associated with the given key,
     * or 0 if the key is not found in the meta data.
     *
     * @param key The key the value is stored under
     * @return an int value
     */
    public int getInt(String key) {
        return mBundle.getInt(key, 0);
    }

    /**
     * Returns a {@link Bitmap} for the given key or null if the key is not found in the meta data.
     *
     * @param key The key the value is stored under
     * @return a {@link Bitmap} or null
     * @deprecated Use getBitmapId(String) instead
     */
    @Deprecated
    public Bitmap getBitmap(String key) {
        Bitmap bmp = null;
        try {
            bmp = mBundle.getParcelable(key);
        } catch (Exception e) {
            // ignore, value was not a bitmap
            Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
        }
        return bmp;
    }

    /**
     * Retrieves an identifier for a bitmap.
     *
     * The format of an identifier is opaque to the application,
     * with a special case of value 0 being invalid.
     * An identifier for a given image-tuner pair is unique, so an application
     * may cache images and determine if there is a necessity to fetch them
     * again - if identifier changes, it means the image has changed.
     *
     * Only bitmap keys may be used with this method:
     * <ul>
     * <li>{@link #METADATA_KEY_ICON}</li>
     * <li>{@link #METADATA_KEY_ART}</li>
     * </ul>
     *
     * @param key The key the value is stored under.
     * @return a bitmap identifier or 0 if it's missing.
     * @hide This API is not thoroughly elaborated yet
     */
    public int getBitmapId(@NonNull String key) {
        if (!METADATA_KEY_ICON.equals(key) && !METADATA_KEY_ART.equals(key)) return 0;
        return getInt(key);
    }

    public Clock getClock(String key) {
        Clock clock = null;
        try {
            clock = mBundle.getParcelable(key);
        } catch (Exception e) {
            // ignore, value was not a clock.
            Log.w(TAG, "Failed to retrieve a key as Clock.", e);
        }
        return clock;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBundle(mBundle);
    }

    /**
     * Returns the number of fields in this meta data.
     *
     * @return the number of fields in the meta data.
     */
    public int size() {
        return mBundle.size();
    }

    /**
     * Returns a Set containing the Strings used as keys in this meta data.
     *
     * @return a Set of String keys
     */
    public Set<String> keySet() {
        return mBundle.keySet();
    }

    /**
     * Helper for getting the String key used by {@link RadioMetadata} from the
     * corrsponding native integer key.
     *
     * @param editorKey The key used by the editor
     * @return the key used by this class or null if no mapping exists
     * @hide
     */
    public static String getKeyFromNativeKey(int nativeKey) {
        return NATIVE_KEY_MAPPING.get(nativeKey, null);
    }

    public static final @android.annotation.NonNull Parcelable.Creator<RadioMetadata> CREATOR =
            new Parcelable.Creator<RadioMetadata>() {
                @Override
                public RadioMetadata createFromParcel(Parcel in) {
                    return new RadioMetadata(in);
                }

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

    /**
     * Use to build RadioMetadata objects.
     */
    public static final class Builder {
        private final Bundle mBundle;

        /**
         * Create an empty Builder. Any field that should be included in the
         * {@link RadioMetadata} must be added.
         */
        public Builder() {
            mBundle = new Bundle();
        }

        /**
         * Create a Builder using a {@link RadioMetadata} instance to set the
         * initial values. All fields in the source meta data will be included in
         * the new meta data. Fields can be overwritten by adding the same key.
         *
         * @param source
         */
        public Builder(RadioMetadata source) {
            mBundle = new Bundle(source.mBundle);
        }

        /**
         * Create a Builder using a {@link RadioMetadata} instance to set
         * initial values, but replace bitmaps with a scaled down copy if they
         * are larger than maxBitmapSize.
         *
         * @param source The original meta data to copy.
         * @param maxBitmapSize The maximum height/width for bitmaps contained
         *            in the meta data.
         * @hide
         */
        public Builder(RadioMetadata source, int maxBitmapSize) {
            this(source);
            for (String key : mBundle.keySet()) {
                Object value = mBundle.get(key);
                if (value != null && value instanceof Bitmap) {
                    Bitmap bmp = (Bitmap) value;
                    if (bmp.getHeight() > maxBitmapSize || bmp.getWidth() > maxBitmapSize) {
                        putBitmap(key, scaleBitmap(bmp, maxBitmapSize));
                    }
                }
            }
        }

        /**
         * Put a String value into the meta data. Custom keys may be used, but if
         * the METADATA_KEYs defined in this class are used they may only be one
         * of the following:
         * <ul>
         * <li>{@link #METADATA_KEY_RDS_PS}</li>
         * <li>{@link #METADATA_KEY_RDS_RT}</li>
         * <li>{@link #METADATA_KEY_TITLE}</li>
         * <li>{@link #METADATA_KEY_ARTIST}</li>
         * <li>{@link #METADATA_KEY_ALBUM}</li>
         * <li>{@link #METADATA_KEY_GENRE}</li>
         * </ul>
         *
         * @param key The key for referencing this value
         * @param value The String value to store
         * @return the same Builder instance
         */
        public Builder putString(String key, String value) {
            if (!METADATA_KEYS_TYPE.containsKey(key) ||
                    METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
                throw new IllegalArgumentException("The " + key
                        + " key cannot be used to put a String");
            }
            mBundle.putString(key, value);
            return this;
        }

        /**
         * Put an int value into the meta data. Custom keys may be used, but if
         * the METADATA_KEYs defined in this class are used they may only be one
         * of the following:
         * <ul>
         * <li>{@link #METADATA_KEY_RDS_PI}</li>
         * <li>{@link #METADATA_KEY_RDS_PTY}</li>
         * <li>{@link #METADATA_KEY_RBDS_PTY}</li>
         * </ul>
         * or any bitmap represented by its identifier.
         *
         * @param key The key for referencing this value
         * @param value The int value to store
         * @return the same Builder instance
         */
        public Builder putInt(String key, int value) {
            RadioMetadata.putInt(mBundle, key, value);
            return this;
        }

        /**
         * Put a {@link Bitmap} into the meta data. Custom keys may be used, but
         * if the METADATA_KEYs defined in this class are used they may only be
         * one of the following:
         * <ul>
         * <li>{@link #METADATA_KEY_ICON}</li>
         * <li>{@link #METADATA_KEY_ART}</li>
         * </ul>
         * <p>
         *
         * @param key The key for referencing this value
         * @param value The Bitmap to store
         * @return the same Builder instance
         */
        public Builder putBitmap(String key, Bitmap value) {
            if (!METADATA_KEYS_TYPE.containsKey(key) ||
                    METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
                throw new IllegalArgumentException("The " + key
                        + " key cannot be used to put a Bitmap");
            }
            mBundle.putParcelable(key, value);
            return this;
        }

        /**
         * Put a {@link RadioMetadata.Clock} into the meta data. Custom keys may be used, but if the
         * METADATA_KEYs defined in this class are used they may only be one of the following:
         * <ul>
         * <li>{@link #MEADATA_KEY_CLOCK}</li>
         * </ul>
         *
         * @param utcSecondsSinceEpoch Number of seconds since epoch for UTC + 0 timezone.
         * @param timezoneOffsetInMinutes Offset of timezone from UTC + 0 in minutes.
         * @return the same Builder instance.
         */
        public Builder putClock(String key, long utcSecondsSinceEpoch, int timezoneOffsetMinutes) {
            if (!METADATA_KEYS_TYPE.containsKey(key) ||
                    METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
                throw new IllegalArgumentException("The " + key
                    + " key cannot be used to put a RadioMetadata.Clock.");
            }
            mBundle.putParcelable(key, new Clock(utcSecondsSinceEpoch, timezoneOffsetMinutes));
            return this;
        }

        /**
         * Creates a {@link RadioMetadata} instance with the specified fields.
         *
         * @return a new {@link RadioMetadata} object
         */
        public RadioMetadata build() {
            return new RadioMetadata(mBundle);
        }

        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
            float maxSizeF = maxSize;
            float widthScale = maxSizeF / bmp.getWidth();
            float heightScale = maxSizeF / bmp.getHeight();
            float scale = Math.min(widthScale, heightScale);
            int height = (int) (bmp.getHeight() * scale);
            int width = (int) (bmp.getWidth() * scale);
            return Bitmap.createScaledBitmap(bmp, width, height, true);
        }
    }

    int putIntFromNative(int nativeKey, int value) {
        String key = getKeyFromNativeKey(nativeKey);
        try {
            putInt(mBundle, key, value);
            return 0;
        } catch (IllegalArgumentException ex) {
            return -1;
        }
    }

    int putStringFromNative(int nativeKey, String value) {
        String key = getKeyFromNativeKey(nativeKey);
        if (!METADATA_KEYS_TYPE.containsKey(key) ||
                METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
            return -1;
        }
        mBundle.putString(key, value);
        return 0;
    }

    int putBitmapFromNative(int nativeKey, byte[] value) {
        String key = getKeyFromNativeKey(nativeKey);
        if (!METADATA_KEYS_TYPE.containsKey(key) ||
                METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
            return -1;
        }
        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeByteArray(value, 0, value.length);
            if (bmp != null) {
                mBundle.putParcelable(key, bmp);
                return 0;
            }
        } catch (Exception e) {
        }
        return -1;
    }

    int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
        String key = getKeyFromNativeKey(nativeKey);
        if (!METADATA_KEYS_TYPE.containsKey(key) ||
                METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
              return -1;
        }
        mBundle.putParcelable(key, new RadioMetadata.Clock(
            utcEpochSeconds, timezoneOffsetInMinutes));
        return 0;
    }
}
