/*
 * Copyright (C) 2017 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.
 */
#pragma once

#include <memory>

#include "guest/hals/audio/audio_hal.h"
#include "guest/hals/audio/simulated_buffer.h"
#include "guest/hals/audio/vsoc_audio_message.h"

namespace cvd {

// Defines static callback functions for the audio_stream and audio_stream_out
// interfaces in  libhardware/include/hardware/audio.h
//
// Where the is a conflict the comments there apply.
// By default these methods return 0 on success -<errno> for failure.
class GceAudioOutputStream : public audio_stream_out {
 public:
  // Factory method for a new output stream.
  static int Open(GceAudio* dev, audio_io_handle_t handle,
                  audio_devices_t devices, audio_output_flags_t flags,
                  audio_config* config, uint32_t stream_number,
                  GceAudioOutputStream** stream_out);

  gce_audio_message GetStreamDescriptor(
      gce_audio_message::message_t message_type) const {
    gce_audio_message rval = message_header_;
    rval.total_size = sizeof(rval);
    rval.header_size = sizeof(rval);
    rval.message_type = message_type;
    rval.num_frames_presented = 0;
    rval.num_frames_accepted = 0;
    return rval;
  }

  // Method from audio_stream, listed in order of appearance.
  // TODO(ghartman): Consider moving these if they could be shared with
  // gce_audio_input_stream.


  // Returns the sampling rate in Hz - eg. 44100.
  uint32_t GetSampleRate() const {
    return message_header_.frame_rate;
  }

  // Sets the sample rate
  //   AUDIO_PARAMETER_STREAM_SAMPLING_RATE
  int SetSampleRate(uint32_t sample_rate) {
    if (sample_rate != message_header_.frame_rate) {
      message_header_.frame_rate = sample_rate;
      // TODO(ghartman): The output buffer should be quantized at about 192
      // bytes for better fidelity. Do this by passing
      // frame_rate * frame_size / 192 and then rescaling the outputs.
      // Or we could always create a quantized wrapper of the buffer...
      buffer_.reset(
          new SimulatedOutputBuffer(
              sample_rate, GetBufferSize() / frame_size_));
    }
    return 0;
  }

  // Returns the size of input/output buffer in bytes for this stream.
  // eg. 4800.
  // It should be a multiple of the frame size.  See also GetInputBufferSize.
  size_t GetBufferSize() const {
    return kOutBufferSize;
  }

  // Returns the channel mask -
  //  e.g. AUDIO_CHANNEL_OUT_STEREO or AUDIO_CHANNEL_IN_STEREO
  audio_channel_mask_t GetChannels() const {
    return message_header_.channel_mask;
  }

  // Returns the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT
  audio_format_t GetFormat() const {
    return message_header_.format;
  }

  // Sets the audio format.
  // Unused as of JB - use set_parameters with key
  //   AUDIO_PARAMETER_STREAM_FORMAT
  int SetFormat(audio_format_t format) {
    message_header_.format = format;
    return 0;
  }

  // Puts the audio hardware input/output into standby mode.
  // Driver should exit from standby mode at the next I/O operation.
  // Returns 0 on success and <0 on failure.
  // TODO(ghartman): This should reset some of the frame counts.
  int Standby() {
    return 0;
  }

  // dumps the state of the audio hardware to the given fd.
  // This information can be retrieved using the dumpsys utility.
  int Dump(int fd) const;

  // Returns the set of device(s) which this stream is connected to.
  // TODO(ghartman): Implement this.
  audio_devices_t GetDevice() const { return device_; }

  // Not directly called from JB forward.
  // Called indirectly from SetParameters with the key
  //   AUDIO_PARAMETER_STREAM_ROUTING
  int SetDevice(audio_devices_t device) { device_ = device; return 0; }

  // Sets audio stream parameters. The function accepts a list of
  // parameter key value pairs in the form: key1=value1;key2=value2;...
  //
  // Some keys are reserved for standard parameters (See AudioParameter class)
  //
  // If the implementation does not accept a parameter change while
  // the output is active but the parameter is acceptable otherwise, it must
  // return -ENOSYS.
  //
  // The audio flinger will put the stream in standby and then change the
  // parameter value.
  int SetParameters(const char* kv_pairs);

  // Gets audio stream parameters. The function accepts a list of
  // keys in the form: key1=value1;key2=value2;...
  //
  // Returns a pointer to a heap allocated string. The caller is responsible
  // for freeing the memory for it using free().
  // TODO(ghartman): Implement this.
  char* GetParameters(const char* keys) const;

  // TODO(ghartman): Implement this.
  int AddAudioEffect(effect_handle_t /*effect*/) const {
    static unsigned int printed = 0;  // printed every 2^32-th call.
    ALOGE_IF(!printed++, "%s: not implemented", __FUNCTION__);
    return 0;
  }

  // TODO(ghartman): Implement this.
  int RemoveAudioEffect(effect_handle_t /*effect*/) const {
    static unsigned int printed = 0;  // printed every 2^32-th call.
    ALOGE_IF(!printed++, "%s: not implemented", __FUNCTION__);
    return 0;
  }

  // Methods defined in audio_stream_out

  // Returns the audio hardware driver estimated latency in milliseconds.
  // TODO(ghartman): Calculate this based on the format and the quantum.
  uint32_t GetLatency() const {
    return kOutLatency;
  }

  // Use this method in situations where audio mixing is done in the
  // hardware. This method serves as a direct interface with hardware,
  // allowing you to directly set the volume as apposed to via the framework.
  // This method might produce multiple PCM outputs or hardware accelerated
  // codecs, such as MP3 or AAC.
  //
  // Note that GCE simulates hardware mixing.
  int SetVolume(float left_volume, float right_volume) {
    left_volume_ = left_volume;
    right_volume_ = right_volume;
    return 0;
  }

  // Write audio buffer to driver. Returns number of bytes written, or a
  // negative android::status_t. If at least one frame was written successfully prior
  // to the error the driver will return that successful (short) byte count
  // and then return an error in the subsequent call.
  //
  // If SetCallback() has previously been called to enable non-blocking mode
  // the Write() is not allowed to block. It must write only the number of
  // bytes that currently fit in the driver/hardware buffer and then return
  // this byte count. If this is less than the requested write size the
  // callback function must be called when more space is available in the
  // driver/hardware buffer.
  ssize_t Write(const void* buffer, size_t bytes);

  // Returns the number of audio frames written by the audio dsp to DAC since
  // the output has exited standby
  // TODO(ghartman): Implement zeroing this in Standby().
  int GetRenderPosition(uint32_t* dsp_frames) const;

  // Gets the local time at which the next write to the audio driver will be
  // presented. The units are microseconds, where the epoch is decided by the
  // local audio HAL.
  //
  // The GCE implementation uses CLOCK_MONOTONIC, which also happens to line
  // up with LocalTime.
  int GetNextWriteTimestamp(int64_t*) const;

  // Turns on non-blocking mode and sets the callback function for notifying
  // completion of non-blocking write and drain.
  // Calling this function implies that all future Write() and Drain()
  // must be non-blocking and use the callback to signal completion.
  //
  // TODO(ghartman): Implement this URGENTLY.
  //
  // int SetCallback(stream_callback_t callback, void *cookie);

  // Notifies to the audio driver to stop playback however the queued buffers
  // are retained by the hardware. Useful for implementing pause/resume. Empty
  // implementation if not supported however should be implemented for hardware
  // with non-trivial latency. In the pause state audio hardware could still be
  // using power. User may consider calling suspend after a timeout.
  //
  // Implementation of this function is mandatory for offloaded playback.
  //
  // TODO(ghartman): Implement this URGENTLY. There is already support in
  // SimulatedBuffer.
  // int Pause();

  // Notifies to the audio driver to resume playback following a pause.
  // Returns error if called without matching pause.
  //
  // Implementation of this function is mandatory for offloaded playback.
  //
  // TODO(ghartman): Implement this URGENTLY.
  //
  // int Resume();

  // Requests notification when data buffered by the driver/hardware has
  // been played. If set_callback() has previously been called to enable
  // non-blocking mode, the drain() must not block, instead it should return
  // quickly and completion of the drain is notified through the callback.
  // If set_callback() has not been called, the drain() must block until
  // completion.
  //
  // If type==AUDIO_DRAIN_ALL, the drain completes when all previously written
  // data has been played.
  //
  // If type==AUDIO_DRAIN_EARLY_NOTIFY, the drain completes shortly before all
  // data for the current track has played to allow time for the framework
  // to perform a gapless track switch.
  //
  // Drain must return immediately on stop() and flush() call
  //
  // Implementation of this function is mandatory for offloaded playback.
  //
  // TODO(ghartman): Implement this URGENTLY.
  //
  // int Drain(audio_drain_type_t type);

  // Notifies to the audio driver to flush the queued data. Stream must already
  // be paused before calling Flush().
  //
  // Implementation of this function is mandatory for offloaded playback.
  //
  // TODO(ghartman): Implement this URGENTLY.
  //
  // int Flush();

  // Returns a recent count of the number of audio frames presented to an
  // external observer.  This excludes frames which have been written but are
  // still in the pipeline.
  //
  // The count is not reset to zero when output enters standby.
  // Also returns the value of CLOCK_MONOTONIC as of this presentation count.
  // The returned count is expected to be 'recent',
  // but does not need to be the most recent possible value.
  // However, the associated time should correspond to whatever count is
  // returned.
  //
  // Example:  assume that N+M frames have been presented, where M is a
  // 'small' number.
  // Then it is permissible to return N instead of N+M,
  // and the timestamp should correspond to N rather than N+M.
  // The terms 'recent' and 'small' are not defined.
  // They reflect the quality of the implementation.
  //
  // 3.0 and higher only.
  //
  // TODO(ghartman): Implement this URGENTLY.
  //
  // int GetPresentationPosition(uint64_t *frames, struct timespec *timestamp);

 private:
  // If key is present in query, add key=value; to reply.
  // query should be pointer to const, but the str_parms functions aren't
  // const-correct, so neither is this.
  static void AddIntIfKeyPresent(
      /*const*/ str_parms* query, str_parms* reply, const char* key, int value);


  explicit GceAudioOutputStream(cvd::GceAudio*);

  static const size_t kOutBufferSize = 3840;
  static const size_t kOutLatency = 2;

  gce_audio_message message_header_;
  std::unique_ptr<SimulatedOutputBuffer> buffer_;
  cvd::GceAudio *dev_;
  audio_devices_t device_;
  size_t frame_size_;
  size_t frame_count_;
  float left_volume_;
  float right_volume_;
};

}
