/*
 * Copyright (C) 2022 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.mediav2.common.cts;

import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;

import android.media.AudioFormat;
import android.media.MediaFormat;

import androidx.annotation.NonNull;

/**
 * Class to hold encoder configuration settings.
 */
public class EncoderConfigParams {
    public static final String TOKEN_SEPARATOR = "<>";

    public final boolean mIsAudio;
    public final String mMediaType;

    // video params
    public final int mWidth;
    public final int mHeight;
    public final int mFrameRate;
    public final float mKeyFrameInterval;
    public final int mMaxBFrames;
    public final int mBitRateMode;
    public final int mLevel;
    public final int mColorFormat;
    public final int mInputBitDepth;
    public final int mRange;
    public final int mStandard;
    public final int mTransfer;

    // audio params
    public final int mSampleRate;
    public final int mChannelCount;
    public final int mCompressionLevel;
    public final int mPcmEncoding;

    // common params
    public final int mProfile;
    public final int mBitRate;

    Builder mBuilder;
    MediaFormat mFormat;
    StringBuilder mMsg;

    private EncoderConfigParams(Builder cfg) {
        if (cfg.mMediaType == null) {
            throw new IllegalArgumentException("null media type");
        }
        mIsAudio = cfg.mMediaType.startsWith("audio/");
        boolean mIsVideo = cfg.mMediaType.startsWith("video/");
        if (mIsAudio == mIsVideo) {
            throw new IllegalArgumentException("invalid media type, it is neither audio nor video");
        }
        mMediaType = cfg.mMediaType;
        if (mIsAudio) {
            if (cfg.mSampleRate <= 0 || cfg.mChannelCount <= 0) {
                throw new IllegalArgumentException("bad config params for audio component");
            }
            mSampleRate = cfg.mSampleRate;
            mChannelCount = cfg.mChannelCount;
            if (mMediaType.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
                if (cfg.mCompressionLevel < 0 || cfg.mCompressionLevel > 8) {
                    throw new IllegalArgumentException("bad compression level for flac component");
                }
                mCompressionLevel = cfg.mCompressionLevel;
                mBitRate = -1;
            } else {
                if (cfg.mBitRate <= 0) {
                    throw new IllegalArgumentException("bad bitrate value for audio component");
                }
                mBitRate = cfg.mBitRate;
                mCompressionLevel = -1;
            }
            if (cfg.mPcmEncoding != AudioFormat.ENCODING_PCM_FLOAT
                    && cfg.mPcmEncoding != AudioFormat.ENCODING_PCM_16BIT) {
                throw new IllegalArgumentException("bad input pcm encoding for audio component");
            }
            if (cfg.mInputBitDepth != -1) {
                throw new IllegalArgumentException(
                        "use pcm encoding to signal input attributes, don't use bitdepth");
            }
            mPcmEncoding = cfg.mPcmEncoding;
            mProfile = cfg.mProfile;

            // satisfy Variable '*' might not have been initialized, unused by this media type
            mWidth = 352;
            mHeight = 288;
            mFrameRate = -1;
            mBitRateMode = -1;
            mKeyFrameInterval = 1.0f;
            mMaxBFrames = 0;
            mLevel = -1;
            mColorFormat = COLOR_FormatYUV420Flexible;
            mInputBitDepth = -1;
            mRange = -1;
            mStandard = -1;
            mTransfer = -1;
        } else {
            if (cfg.mWidth <= 0 || cfg.mHeight <= 0) {
                throw new IllegalArgumentException("bad config params for video component");
            }
            mWidth = cfg.mWidth;
            mHeight = cfg.mHeight;
            if (cfg.mFrameRate <= 0) {
                if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
                    mFrameRate = 12;
                } else if (mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_H263)) {
                    mFrameRate = 12;
                } else {
                    mFrameRate = 30;
                }
            } else {
                mFrameRate = cfg.mFrameRate;
            }
            if (cfg.mBitRate <= 0) {
                throw new IllegalArgumentException("bad bitrate value for video component");
            }
            mBitRate = cfg.mBitRate;
            mKeyFrameInterval = cfg.mKeyFrameInterval;
            mMaxBFrames = cfg.mMaxBFrames;
            mBitRateMode = cfg.mBitRateMode;
            mProfile = cfg.mProfile;
            mLevel = cfg.mLevel;
            if (cfg.mColorFormat != COLOR_FormatYUV420Flexible
                    && cfg.mColorFormat != COLOR_FormatYUVP010
                    && cfg.mColorFormat != COLOR_FormatSurface
                    && cfg.mColorFormat != COLOR_FormatYUV420SemiPlanar
                    && cfg.mColorFormat != COLOR_FormatYUV420Planar) {
                throw new IllegalArgumentException("bad color format config for video component");
            }
            mColorFormat = cfg.mColorFormat;
            if (cfg.mInputBitDepth != -1) {
                if (cfg.mColorFormat == COLOR_FormatYUV420Flexible && cfg.mInputBitDepth != 8) {
                    throw new IllegalArgumentException(
                            "bad bit depth configuration for COLOR_FormatYUV420Flexible");
                } else if (cfg.mColorFormat == COLOR_FormatYUV420SemiPlanar
                        && cfg.mInputBitDepth != 8) {
                    throw new IllegalArgumentException(
                            "bad bit depth configuration for COLOR_FormatYUV420SemiPlanar");
                } else if (cfg.mColorFormat == COLOR_FormatYUV420Planar
                        && cfg.mInputBitDepth != 8) {
                    throw new IllegalArgumentException(
                            "bad bit depth configuration for COLOR_FormatYUV420Planar");
                } else if (cfg.mColorFormat == COLOR_FormatYUVP010 && cfg.mInputBitDepth != 10) {
                    throw new IllegalArgumentException(
                            "bad bit depth configuration for COLOR_FormatYUVP010");
                } else if (cfg.mColorFormat == COLOR_FormatSurface && cfg.mInputBitDepth != 8
                        && cfg.mInputBitDepth != 10) {
                    throw new IllegalArgumentException(
                            "bad bit depth configuration for COLOR_FormatSurface");
                }
                mInputBitDepth = cfg.mInputBitDepth;
            } else if (cfg.mColorFormat == COLOR_FormatYUVP010) {
                mInputBitDepth = 10;
            } else {
                mInputBitDepth = 8;
            }
            mRange = cfg.mRange;
            mStandard = cfg.mStandard;
            mTransfer = cfg.mTransfer;

            // satisfy Variable '*' might not have been initialized, unused by this media type
            mSampleRate = 8000;
            mChannelCount = 1;
            mCompressionLevel = 5;
            mPcmEncoding = AudioFormat.ENCODING_INVALID;
        }
        mBuilder = cfg;
    }

    public Builder getBuilder() throws CloneNotSupportedException {
        return mBuilder.clone();
    }

    public MediaFormat getFormat() {
        if (mFormat != null) return new MediaFormat(mFormat);

        mFormat = new MediaFormat();
        mFormat.setString(MediaFormat.KEY_MIME, mMediaType);
        if (mIsAudio) {
            mFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRate);
            mFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, mChannelCount);
            if (mMediaType.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
                mFormat.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, mCompressionLevel);
            } else {
                mFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
            }
            if (mProfile >= 0 && mMediaType.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
                mFormat.setInteger(MediaFormat.KEY_PROFILE, mProfile);
                mFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, mProfile);
            }
            mFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, mPcmEncoding);
        } else {
            mFormat.setInteger(MediaFormat.KEY_WIDTH, mWidth);
            mFormat.setInteger(MediaFormat.KEY_HEIGHT, mHeight);
            mFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
            mFormat.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
            mFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, mKeyFrameInterval);
            mFormat.setInteger(MediaFormat.KEY_MAX_B_FRAMES, mMaxBFrames);
            if (mBitRateMode >= 0) mFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, mBitRateMode);
            if (mProfile >= 0) mFormat.setInteger(MediaFormat.KEY_PROFILE, mProfile);
            if (mLevel >= 0) mFormat.setInteger(MediaFormat.KEY_LEVEL, mLevel);
            mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
            if (mRange >= 0) mFormat.setInteger(MediaFormat.KEY_COLOR_RANGE, mRange);
            if (mStandard >= 0) mFormat.setInteger(MediaFormat.KEY_COLOR_STANDARD, mStandard);
            if (mTransfer >= 0) mFormat.setInteger(MediaFormat.KEY_COLOR_TRANSFER, mTransfer);
        }
        return new MediaFormat(mFormat);
    }

    /**
     * Converts MediaFormat object to a string. All Keys, ValueTypes, Values are concatenated with
     * a separator and sent for further usage.
     */
    public static String serializeMediaFormat(MediaFormat format) {
        StringBuilder msg = new StringBuilder();
        java.util.Set<String> keys = format.getKeys();
        for (String key : keys) {
            int valueTypeForKey = format.getValueTypeForKey(key);
            msg.append(key).append(TOKEN_SEPARATOR);
            msg.append(valueTypeForKey).append(TOKEN_SEPARATOR);
            if (valueTypeForKey == MediaFormat.TYPE_INTEGER) {
                msg.append(format.getInteger(key)).append(TOKEN_SEPARATOR);
            } else if (valueTypeForKey == MediaFormat.TYPE_FLOAT) {
                msg.append(format.getFloat(key)).append(TOKEN_SEPARATOR);
            } else if (valueTypeForKey == MediaFormat.TYPE_STRING) {
                msg.append(format.getString(key)).append(TOKEN_SEPARATOR);
            } else {
                throw new RuntimeException("unrecognized Type for Key: " + key);
            }
        }
        return msg.toString();
    }

    @NonNull
    @Override
    public String toString() {
        if (mMsg != null) return mMsg.toString();

        mMsg = new StringBuilder();
        mMsg.append(String.format("media type : %s, ", mMediaType));
        if (mIsAudio) {
            mMsg.append(String.format("Sample rate : %d, ", mSampleRate));
            mMsg.append(String.format("Channel count : %d, ", mChannelCount));
            if (mMediaType.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
                mMsg.append(String.format("Compression level : %d, ", mCompressionLevel));
            } else {
                mMsg.append(String.format("Bitrate : %d, ", mBitRate));
            }
            if (mMediaType.equals(MediaFormat.MIMETYPE_AUDIO_AAC) && mProfile != -1) {
                mMsg.append(String.format("Profile : %d, ", mProfile));
            }
            mMsg.append(String.format("encoding : %d, ", mPcmEncoding));
        } else {
            mMsg.append(String.format("Width : %d, ", mWidth));
            mMsg.append(String.format("Height : %d, ", mHeight));
            mMsg.append(String.format("Frame rate : %d, ", mFrameRate));
            mMsg.append(String.format("Bit rate : %d, ", mBitRate));
            mMsg.append(String.format("key frame interval : %f, ", mKeyFrameInterval));
            mMsg.append(String.format("max b frames : %d, ", mMaxBFrames));
            if (mBitRateMode >= 0) mMsg.append(String.format("bitrate mode : %d, ", mBitRateMode));
            if (mProfile >= 0) mMsg.append(String.format("profile : %x, ", mProfile));
            if (mLevel >= 0) mMsg.append(String.format("level : %x, ", mLevel));
            mMsg.append(String.format("color format : %x, ", mColorFormat));
            if (mColorFormat == COLOR_FormatSurface) {
                mMsg.append(String.format("bit depth : %d, ", mInputBitDepth));
            }
            if (mRange >= 0) mMsg.append(String.format("color range : %d, ", mRange));
            if (mStandard >= 0) mMsg.append(String.format("color standard : %d, ", mStandard));
            if (mTransfer >= 0) mMsg.append(String.format("color transfer : %d, ", mTransfer));
        }
        mMsg.append("\n");
        return mMsg.toString();
    }

    public static class Builder implements Cloneable {
        public String mMediaType;

        // video params
        public int mWidth = 352;
        public int mHeight = 288;
        public int mFrameRate = -1;
        public int mBitRateMode = -1;
        public float mKeyFrameInterval = 1.0f;
        public int mMaxBFrames = 0;
        public int mLevel = -1;
        public int mColorFormat = COLOR_FormatYUV420Flexible;
        public int mInputBitDepth = -1;
        public int mRange = -1;
        public int mStandard = -1;
        public int mTransfer = -1;

        // audio params
        public int mSampleRate = 8000;
        public int mChannelCount = 1;
        public int mCompressionLevel = 5;
        public int mPcmEncoding = AudioFormat.ENCODING_PCM_16BIT;

        // common params
        public int mProfile = -1;
        public int mBitRate = 256000;

        public Builder(String mediaType) {
            mMediaType = mediaType;
        }

        public Builder setWidth(int width) {
            this.mWidth = width;
            return this;
        }

        public Builder setHeight(int height) {
            this.mHeight = height;
            return this;
        }

        public Builder setFrameRate(int frameRate) {
            this.mFrameRate = frameRate;
            return this;
        }

        public Builder setBitRateMode(int bitRateMode) {
            this.mBitRateMode = bitRateMode;
            return this;
        }

        public Builder setKeyFrameInterval(float keyFrameInterval) {
            this.mKeyFrameInterval = keyFrameInterval;
            return this;
        }

        public Builder setMaxBFrames(int maxBFrames) {
            this.mMaxBFrames = maxBFrames;
            return this;
        }

        public Builder setLevel(int level) {
            this.mLevel = level;
            return this;
        }

        public Builder setColorFormat(int colorFormat) {
            this.mColorFormat = colorFormat;
            return this;
        }

        public Builder setInputBitDepth(int inputBitDepth) {
            this.mInputBitDepth = inputBitDepth;
            return this;
        }

        public Builder setRange(int range) {
            this.mRange = range;
            return this;
        }

        public Builder setStandard(int standard) {
            this.mStandard = standard;
            return this;
        }

        public Builder setTransfer(int transfer) {
            this.mTransfer = transfer;
            return this;
        }

        public Builder setSampleRate(int sampleRate) {
            this.mSampleRate = sampleRate;
            return this;
        }

        public Builder setChannelCount(int channelCount) {
            this.mChannelCount = channelCount;
            return this;
        }

        public Builder setCompressionLevel(int compressionLevel) {
            this.mCompressionLevel = compressionLevel;
            return this;
        }

        public Builder setPcmEncoding(int pcmEncoding) {
            this.mPcmEncoding = pcmEncoding;
            return this;
        }

        public Builder setProfile(int profile) {
            this.mProfile = profile;
            return this;
        }

        public Builder setBitRate(int bitRate) {
            this.mBitRate = bitRate;
            return this;
        }

        public EncoderConfigParams build() {
            return new EncoderConfigParams(this);
        }

        @NonNull
        public Builder clone() throws CloneNotSupportedException {
            return (Builder) super.clone();
        }
    }
}
