/*
 * Copyright (C) 2016 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.
 */
#include "guest/hals/audio/legacy/audio_hal.h"

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>

extern "C" {
#include <cutils/str_parms.h>
}

#include "common/libs/auto_resources/auto_resources.h"
#include "common/libs/fs/shared_select.h"
#include "common/libs/threads/cuttlefish_thread.h"
#include "common/libs/threads/thunkers.h"
#include "common/vsoc/lib/circqueue_impl.h"
#include "guest/hals/audio/legacy/vsoc_audio.h"
#include "guest/hals/audio/legacy/vsoc_audio_input_stream.h"
#include "guest/hals/audio/legacy/vsoc_audio_output_stream.h"
#include "guest/libs/remoter/remoter_framework_pkt.h"

using cvd::LockGuard;
using cvd::Mutex;

namespace cvd {

GceAudio::~GceAudio() { }

int GceAudio::Close() {
  D("GceAudio::%s", __FUNCTION__);
  {
    LockGuard<Mutex> guard(lock_);
    for (std::list<GceAudioOutputStream*>::iterator it = output_list_.begin();
         it != output_list_.end(); ++it) {
      delete *it;
    }
    for (input_map_t::iterator it = input_map_.begin();
         it != input_map_.end(); ++it) {
      delete it->second;
    }
  }
  delete this;
  return 0;
}

size_t GceAudio::GetInputBufferSize(const audio_config*) const {
  return IN_BUFFER_BYTES;
}

uint32_t GceAudio::GetSupportedDevices() const {
  return AUDIO_DEVICE_OUT_EARPIECE |
      AUDIO_DEVICE_OUT_SPEAKER |
      AUDIO_DEVICE_OUT_DEFAULT |
      AUDIO_DEVICE_IN_COMMUNICATION |
      AUDIO_DEVICE_IN_BUILTIN_MIC |
      AUDIO_DEVICE_IN_WIRED_HEADSET |
      AUDIO_DEVICE_IN_VOICE_CALL |
      AUDIO_DEVICE_IN_DEFAULT;
}

int GceAudio::InitCheck() const {
  D("GceAudio::%s", __FUNCTION__);
  return 0;
}

int GceAudio::SetMicMute(bool state) {
  D("GceAudio::%s", __FUNCTION__);
  LockGuard<Mutex> guard(lock_);
  mic_muted_ = state;
  return 0;
}

int GceAudio::GetMicMute(bool *state) const {
  D("GceAudio::%s", __FUNCTION__);
  LockGuard<Mutex> guard(lock_);
  *state = mic_muted_;
  return 0;
}

int GceAudio::OpenInputStream(audio_io_handle_t handle,
                              audio_devices_t devices,
                              audio_config *config,
                              audio_stream_in **stream_in,
                              audio_input_flags_t /*flags*/,
                              const char * /*address*/,
                              audio_source_t /*source*/) {
  GceAudioInputStream* new_stream;
  int rval = GceAudioInputStream::Open(
      this, handle, devices, *config, &new_stream);
  uint32_t stream_number;
  if (new_stream) {
    LockGuard<Mutex> guard(lock_);
    stream_number = next_stream_number_++;
    input_map_[stream_number] = new_stream;
  }
  // This should happen after the lock is released, hence the double check
  if (new_stream) {
    SendStreamUpdate(new_stream->GetStreamDescriptor(
        stream_number, gce_audio_message::OPEN_INPUT_STREAM), MSG_DONTWAIT);
  }
  *stream_in = new_stream;
  return rval;
}


void GceAudio::CloseInputStream(audio_stream_in *stream) {
  GceAudioInputStream* astream = static_cast<GceAudioInputStream*>(stream);
  gce_audio_message descriptor;
  {
    LockGuard<Mutex> guard(lock_);
    // TODO(ghartman): This could be optimized if stream knew it's number.
    for (input_map_t::iterator it = input_map_.begin();
         it != input_map_.end(); ++it) {
      if (it->second == stream) {
        descriptor = it->second->GetStreamDescriptor(
            it->first, gce_audio_message::CLOSE_INPUT_STREAM);
        input_map_.erase(it);
        break;
      }
    }
  }
  SendStreamUpdate(descriptor, MSG_DONTWAIT);
  delete astream;
}


int GceAudio::OpenOutputStream(audio_io_handle_t handle,
                               audio_devices_t devices,
                               audio_output_flags_t flags,
                               audio_config *config,
                               audio_stream_out **stream_out,
                               const char * /*address*/) {
  GceAudioOutputStream* new_stream;
  int rval;
  {
    LockGuard<Mutex> guard(lock_);
    rval = GceAudioOutputStream::Open(
        this, handle, devices, flags, config, next_stream_number_++,
        &new_stream);
    if (new_stream) {
      output_list_.push_back(new_stream);
    }
  }
  if (new_stream) {
    SendStreamUpdate(new_stream->GetStreamDescriptor(
        gce_audio_message::OPEN_OUTPUT_STREAM), MSG_DONTWAIT);
  }
  *stream_out = new_stream;
  return rval;
}

void GceAudio::CloseOutputStream(audio_stream_out *stream) {
  GceAudioOutputStream* astream = static_cast<GceAudioOutputStream*>(stream);
  gce_audio_message close;
  {
    LockGuard<Mutex> guard(lock_);
    output_list_.remove(astream);
    close = astream->GetStreamDescriptor(
        gce_audio_message::CLOSE_OUTPUT_STREAM);
  }
  SendStreamUpdate(close, MSG_DONTWAIT);
  delete astream;
}

int GceAudio::Dump(int fd) const {
  LockGuard<Mutex> guard(lock_);
  dprintf(
      fd,
      "\nadev_dump:\n"
      "\tmic_mute: %s\n"
      "\tnum_outputs: %zu\n"
      "\tnum_inputs: %zu\n\n",
      mic_muted_ ? "true": "false",
      output_list_.size(), input_map_.size());

  for (std::list<GceAudioOutputStream*>::const_iterator it =
           output_list_.begin();
       it != output_list_.end(); ++it) {
    (*it)->common.dump(&(*it)->common, fd);
  }

  for (input_map_t::const_iterator it = input_map_.begin();
       it != input_map_.end(); ++it) {
    (*it).second->common.dump(&(*it).second->common, fd);
  }

  return 0;
}

ssize_t GceAudio::SendMsg(const msghdr& msg, int /* flags */) {
    intptr_t res = audio_data_rv_->data()->audio_queue.Writev(
            audio_data_rv_,
            msg.msg_iov,
            msg.msg_iovlen,
            true /* non_blocking */);

    if (res < 0) {
        ALOGV("GceAudio::%s: CircularPacketQueue::Write returned %" PRIiPTR,
              __FUNCTION__,
              res);
    }

    return static_cast<ssize_t>(res);
}

ssize_t GceAudio::SendStreamUpdate(
    const gce_audio_message& stream_info, int flags) {
  msghdr msg;
  iovec msg_iov[1];
  msg_iov[0].iov_base = const_cast<gce_audio_message*>(&stream_info);
  msg_iov[0].iov_len = sizeof(gce_audio_message);
  msg.msg_name = NULL;
  msg.msg_namelen = 0;
  msg.msg_iov = msg_iov;
  msg.msg_iovlen = arraysize(msg_iov);
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_flags = 0;
  return SendMsg(msg, flags);
}

int GceAudio::SetVoiceVolume(float volume) {
  D("GceAudio::%s: set voice volume %f", __FUNCTION__, volume);
  voice_volume_ = volume;
  return 0;
}

int GceAudio::SetMasterVolume(float volume) {
  D("GceAudio::%s: set master volume %f", __FUNCTION__, volume);
  master_volume_ = volume;
  return 0;
}

int GceAudio::GetMasterVolume(float* volume) {
  D("GceAudio::%s: get master volume %f", __FUNCTION__, master_volume_);
  *volume = master_volume_;
  return 0;
}

int GceAudio::SetMasterMute(bool muted) {
  D("GceAudio::%s: set master muted %d", __FUNCTION__, muted);
  master_muted_ = muted;
  return 0;
}

int GceAudio::GetMasterMute(bool* muted) {
  D("GceAudio::%s: get master muted %d", __FUNCTION__, master_muted_);
  *muted = master_muted_;
  return 0;
}

int GceAudio::SetMode(audio_mode_t mode) {
  D("GceAudio::%s: new mode %d", __FUNCTION__, mode);
  mode_ = mode;
  return 0;
}

int GceAudio::Open(const hw_module_t* module, const char* name,
                   hw_device_t** device) {
  D("GceAudio::%s", __FUNCTION__);

  if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) {
    ALOGE("GceAudio::%s: invalid module name %s (expected %s)",
          __FUNCTION__, name, AUDIO_HARDWARE_INTERFACE);
    return -EINVAL;
  }

  GceAudio* rval = new GceAudio;

  rval->audio_data_rv_ = AudioDataRegionView::GetInstance();
  rval->audio_worker_ = rval->audio_data_rv_->StartWorker();

  rval->common.tag = HARDWARE_DEVICE_TAG;
  rval->common.version = version_;
  rval->common.module = const_cast<hw_module_t *>(module);
  rval->common.close = cvd::thunk<hw_device_t, &GceAudio::Close>;

#if !defined(AUDIO_DEVICE_API_VERSION_2_0)
  // This HAL entry is supported only on AUDIO_DEVICE_API_VERSION_1_0.
  // In fact, with version 2.0 the device numbers were orgainized in a
  // way that makes the return value nonsense.
  // Skipping the assignment is ok: the memset in the constructor already
  // put a NULL here.
  rval->get_supported_devices =
      cvd::thunk<audio_hw_device, &GceAudio::GetSupportedDevices>;
#endif
  rval->init_check = cvd::thunk<audio_hw_device, &GceAudio::InitCheck>;

  rval->set_voice_volume =
      cvd::thunk<audio_hw_device, &GceAudio::SetVoiceVolume>;
  rval->set_master_volume =
      cvd::thunk<audio_hw_device, &GceAudio::SetMasterVolume>;
  rval->get_master_volume =
      cvd::thunk<audio_hw_device, &GceAudio::GetMasterVolume>;

#if defined(AUDIO_DEVICE_API_VERSION_2_0)
  rval->set_master_mute =
      cvd::thunk<audio_hw_device, &GceAudio::SetMasterMute>;
  rval->get_master_mute =
      cvd::thunk<audio_hw_device, &GceAudio::GetMasterMute>;
#endif

  rval->set_mode = cvd::thunk<audio_hw_device, &GceAudio::SetMode>;
  rval->set_mic_mute = cvd::thunk<audio_hw_device, &GceAudio::SetMicMute>;
  rval->get_mic_mute = cvd::thunk<audio_hw_device, &GceAudio::GetMicMute>;

  rval->set_parameters = cvd::thunk<audio_hw_device, &GceAudio::SetParameters>;
  rval->get_parameters = cvd::thunk<audio_hw_device, &GceAudio::GetParameters>;

  rval->get_input_buffer_size =
      cvd::thunk<audio_hw_device, &GceAudio::GetInputBufferSize>;

  rval->open_input_stream =
      cvd::thunk<audio_hw_device, &GceAudio::OpenInputStreamCurrentHAL>;
  rval->close_input_stream =
      cvd::thunk<audio_hw_device, &GceAudio::CloseInputStream>;

  rval->open_output_stream =
      cvd::thunk<audio_hw_device, &GceAudio::OpenOutputStreamCurrentHAL>;
  rval->close_output_stream =
      cvd::thunk<audio_hw_device, &GceAudio::CloseOutputStream>;

  rval->dump = cvd::thunk<audio_hw_device, &GceAudio::Dump>;

  *device = &rval->common;
  return 0;
}

int GceAudio::SetParameters(const char *kvpairs) {
  ALOGE("GceAudio::%s: not implemented", __FUNCTION__);
  if (kvpairs) D("GceAudio::%s: kvpairs %s", __FUNCTION__, kvpairs);
  return 0;
}


char* GceAudio::GetParameters(const char *keys) const {
  ALOGE("GceAudio::%s: not implemented", __FUNCTION__);
  if (keys) D("GceAudio::%s: kvpairs %s", __FUNCTION__, keys);
  return strdup("");
}

int GceAudio::SetStreamParameters(
    struct audio_stream *stream, const char *kv_pairs) {
  struct str_parms *parms = str_parms_create_str(kv_pairs);
  if (!parms) {
    return 0;
  }
  int sample_rate;
  if (str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_SAMPLING_RATE,
                        &sample_rate) >= 0) {
    stream->set_sample_rate(stream, sample_rate);
  }
  int format;
  if (str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_FORMAT,
                        &format) >= 0) {
    stream->set_format(stream, static_cast<audio_format_t>(format));
  }
  int routing;
  if (str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_ROUTING,
                        &routing) >= 0) {
    stream->set_device(stream, static_cast<audio_devices_t>(routing));
  }
  if (str_parms_get_int(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE,
                        &routing) >= 0) {
    stream->set_device(stream, static_cast<audio_devices_t>(routing));
  }
  str_parms_destroy(parms);
  return 0;
}

}
