/*
 *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import android.graphics.SurfaceTexture;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCrypto;
import android.media.MediaFormat;
import android.os.Bundle;
import android.view.Surface;
import androidx.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * Fake MediaCodec that implements the basic state machine.
 *
 * @note This class is only intended for single-threaded tests and is not thread-safe.
 */
public class FakeMediaCodecWrapper implements MediaCodecWrapper {
  private static final int NUM_INPUT_BUFFERS = 10;
  private static final int NUM_OUTPUT_BUFFERS = 10;
  private static final int MAX_ENCODED_DATA_SIZE_BYTES = 1_000;

  /**
   * MediaCodec state as defined by:
   * https://developer.android.com/reference/android/media/MediaCodec.html
   */
  public enum State {
    STOPPED_CONFIGURED(Primary.STOPPED),
    STOPPED_UNINITIALIZED(Primary.STOPPED),
    STOPPED_ERROR(Primary.STOPPED),
    EXECUTING_FLUSHED(Primary.EXECUTING),
    EXECUTING_RUNNING(Primary.EXECUTING),
    EXECUTING_END_OF_STREAM(Primary.EXECUTING),
    RELEASED(Primary.RELEASED);

    public enum Primary { STOPPED, EXECUTING, RELEASED }

    private final Primary primary;

    State(Primary primary) {
      this.primary = primary;
    }

    public Primary getPrimary() {
      return primary;
    }
  }

  /** Represents an output buffer that will be returned by dequeueOutputBuffer. */
  public static class QueuedOutputBufferInfo {
    private int index;
    private int offset;
    private int size;
    private long presentationTimeUs;
    private int flags;

    private QueuedOutputBufferInfo(
        int index, int offset, int size, long presentationTimeUs, int flags) {
      this.index = index;
      this.offset = offset;
      this.size = size;
      this.presentationTimeUs = presentationTimeUs;
      this.flags = flags;
    }

    public static QueuedOutputBufferInfo create(
        int index, int offset, int size, long presentationTimeUs, int flags) {
      return new QueuedOutputBufferInfo(index, offset, size, presentationTimeUs, flags);
    }

    public int getIndex() {
      return index;
    }

    public int getOffset() {
      return offset;
    }

    public int getSize() {
      return size;
    }

    public long getPresentationTimeUs() {
      return presentationTimeUs;
    }

    public int getFlags() {
      return flags;
    }
  }

  private State state = State.STOPPED_UNINITIALIZED;
  private @Nullable MediaFormat configuredFormat;
  private int configuredFlags;
  private final ByteBuffer[] inputBuffers = new ByteBuffer[NUM_INPUT_BUFFERS];
  private final ByteBuffer[] outputBuffers = new ByteBuffer[NUM_OUTPUT_BUFFERS];
  private final boolean[] inputBufferReserved = new boolean[NUM_INPUT_BUFFERS];
  private final boolean[] outputBufferReserved = new boolean[NUM_OUTPUT_BUFFERS];
  private final List<QueuedOutputBufferInfo> queuedOutputBuffers = new ArrayList<>();

  public FakeMediaCodecWrapper() {}

  /** Returns the current simulated state of MediaCodec. */
  public State getState() {
    return state;
  }

  /** Gets the last configured media format passed to configure. */
  public @Nullable MediaFormat getConfiguredFormat() {
    return configuredFormat;
  }

  /** Returns the last flags passed to configure. */
  public int getConfiguredFlags() {
    return configuredFlags;
  }

  /**
   * Adds a texture buffer that will be returned by dequeueOutputBuffer. Returns index of the
   * buffer.
   */
  public int addOutputTexture(long presentationTimestampUs, int flags) {
    int index = getFreeOutputBuffer();
    queuedOutputBuffers.add(QueuedOutputBufferInfo.create(
        index, /* offset= */ 0, /* size= */ 0, presentationTimestampUs, flags));
    return index;
  }

  /**
   * Adds a byte buffer buffer that will be returned by dequeueOutputBuffer. Returns index of the
   * buffer.
   */
  public int addOutputData(byte[] data, long presentationTimestampUs, int flags) {
    int index = getFreeOutputBuffer();
    ByteBuffer outputBuffer = outputBuffers[index];

    outputBuffer.clear();
    outputBuffer.put(data);
    outputBuffer.rewind();

    queuedOutputBuffers.add(QueuedOutputBufferInfo.create(
        index, /* offset= */ 0, data.length, presentationTimestampUs, flags));
    return index;
  }

  /**
   * Returns the first output buffer that is not reserved and reserves it. It will be stay reserved
   * until released with releaseOutputBuffer.
   */
  private int getFreeOutputBuffer() {
    for (int i = 0; i < NUM_OUTPUT_BUFFERS; i++) {
      if (!outputBufferReserved[i]) {
        outputBufferReserved[i] = true;
        return i;
      }
    }
    throw new RuntimeException("All output buffers reserved!");
  }

  @Override
  public void configure(MediaFormat format, Surface surface, MediaCrypto crypto, int flags) {
    if (state != State.STOPPED_UNINITIALIZED) {
      throw new IllegalStateException("Expected state STOPPED_UNINITIALIZED but was " + state);
    }
    state = State.STOPPED_CONFIGURED;
    configuredFormat = format;
    configuredFlags = flags;

    final int width = configuredFormat.getInteger(MediaFormat.KEY_WIDTH);
    final int height = configuredFormat.getInteger(MediaFormat.KEY_HEIGHT);
    final int yuvSize = width * height * 3 / 2;
    final int inputBufferSize;
    final int outputBufferSize;

    if ((flags & MediaCodec.CONFIGURE_FLAG_ENCODE) != 0) {
      final int colorFormat = configuredFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);

      inputBufferSize = colorFormat == CodecCapabilities.COLOR_FormatSurface ? 0 : yuvSize;
      outputBufferSize = MAX_ENCODED_DATA_SIZE_BYTES;
    } else {
      inputBufferSize = MAX_ENCODED_DATA_SIZE_BYTES;
      outputBufferSize = surface != null ? 0 : yuvSize;
    }

    for (int i = 0; i < inputBuffers.length; i++) {
      inputBuffers[i] = ByteBuffer.allocateDirect(inputBufferSize);
    }
    for (int i = 0; i < outputBuffers.length; i++) {
      outputBuffers[i] = ByteBuffer.allocateDirect(outputBufferSize);
    }
  }

  @Override
  public void start() {
    if (state != State.STOPPED_CONFIGURED) {
      throw new IllegalStateException("Expected state STOPPED_CONFIGURED but was " + state);
    }
    state = State.EXECUTING_RUNNING;
  }

  @Override
  public void flush() {
    if (state.getPrimary() != State.Primary.EXECUTING) {
      throw new IllegalStateException("Expected state EXECUTING but was " + state);
    }
    state = State.EXECUTING_FLUSHED;
  }

  @Override
  public void stop() {
    if (state.getPrimary() != State.Primary.EXECUTING) {
      throw new IllegalStateException("Expected state EXECUTING but was " + state);
    }
    state = State.STOPPED_UNINITIALIZED;
  }

  @Override
  public void release() {
    state = State.RELEASED;
  }

  @Override
  public int dequeueInputBuffer(long timeoutUs) {
    if (state != State.EXECUTING_FLUSHED && state != State.EXECUTING_RUNNING) {
      throw new IllegalStateException(
          "Expected state EXECUTING_FLUSHED or EXECUTING_RUNNING but was " + state);
    }
    state = State.EXECUTING_RUNNING;

    for (int i = 0; i < NUM_INPUT_BUFFERS; i++) {
      if (!inputBufferReserved[i]) {
        inputBufferReserved[i] = true;
        return i;
      }
    }
    return MediaCodec.INFO_TRY_AGAIN_LATER;
  }

  @Override
  public void queueInputBuffer(
      int index, int offset, int size, long presentationTimeUs, int flags) {
    if (state.getPrimary() != State.Primary.EXECUTING) {
      throw new IllegalStateException("Expected state EXECUTING but was " + state);
    }
    if (flags != 0) {
      throw new UnsupportedOperationException(
          "Flags are not implemented in FakeMediaCodecWrapper.");
    }
  }

  @Override
  public int dequeueOutputBuffer(MediaCodec.BufferInfo info, long timeoutUs) {
    if (state.getPrimary() != State.Primary.EXECUTING) {
      throw new IllegalStateException("Expected state EXECUTING but was " + state);
    }

    if (queuedOutputBuffers.isEmpty()) {
      return MediaCodec.INFO_TRY_AGAIN_LATER;
    }
    QueuedOutputBufferInfo outputBufferInfo = queuedOutputBuffers.remove(/* index= */ 0);
    info.set(outputBufferInfo.getOffset(), outputBufferInfo.getSize(),
        outputBufferInfo.getPresentationTimeUs(), outputBufferInfo.getFlags());
    return outputBufferInfo.getIndex();
  }

  @Override
  public void releaseOutputBuffer(int index, boolean render) {
    if (state.getPrimary() != State.Primary.EXECUTING) {
      throw new IllegalStateException("Expected state EXECUTING but was " + state);
    }
    if (!outputBufferReserved[index]) {
      throw new RuntimeException("Released output buffer was not in use.");
    }
    outputBufferReserved[index] = false;
  }

  @Override
  public ByteBuffer getInputBuffer(int index) {
    return inputBuffers[index];
  }

  @Override
  public ByteBuffer getOutputBuffer(int index) {
    return outputBuffers[index];
  }

  @Override
  public MediaFormat getInputFormat() {
    return new MediaFormat();
  }

  @Override
  public MediaFormat getOutputFormat() {
    return new MediaFormat();
  }

  @Override
  public MediaFormat getOutputFormat(int index) {
    return new MediaFormat();
  }

  @Override
  public Surface createInputSurface() {
    return new Surface(new SurfaceTexture(/* texName= */ 0));
  }

  @Override
  public void setParameters(Bundle params) {}

  @Override
  public MediaCodecInfo getCodecInfo() {
    return null;
  }
}
