//
// Copyright (C) 2020 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 "host/libs/audio_connector/commands.h"

#include <android-base/logging.h>

#include "host/libs/audio_connector/shm_layout.h"

namespace cuttlefish {

AudioCommand::~AudioCommand() {
  CHECK(status_ != AudioStatus::NOT_SET)
      << "A command of type " << static_cast<uint32_t>(type())
      << " went out of scope without reply";
}

StreamInfoCommand::StreamInfoCommand(uint32_t start_id, size_t count,
                                     virtio_snd_pcm_info* pcm_info)
    : InfoCommand(AudioCommandType::VIRTIO_SND_R_PCM_INFO, start_id, count,
                  pcm_info) {}

void StreamInfoCommand::Reply(AudioStatus status,
                              const std::vector<virtio_snd_pcm_info>& reply) {
  MarkReplied(status);
  if (status != AudioStatus::VIRTIO_SND_S_OK) {
    return;
  }
  CHECK(reply.size() == count())
      << "Returned unmatching info count: " << reply.size() << " vs "
      << count();
  for (int i = 0; i < reply.size(); ++i) {
    info_reply()[i].hdr.hda_fn_nid = Le32(reply[i].hdr.hda_fn_nid);
    info_reply()[i].features = Le32(reply[i].features);
    info_reply()[i].formats = Le64(reply[i].formats);
    info_reply()[i].rates = Le64(reply[i].rates);
    info_reply()[i].direction = reply[i].direction;
    info_reply()[i].channels_min = reply[i].channels_min;
    info_reply()[i].channels_max = reply[i].channels_max;
    // pcm_info[i].padding is supposed to be all zeros in virtio-snd but here we
    // can just ignore it.
  }
}

StreamControlCommand::StreamControlCommand(AudioCommandType type,
                                           uint32_t stream_id)
    : AudioCommand(type), stream_id_(stream_id) {}

void StreamControlCommand::Reply(AudioStatus status) {
  // These commands don't expect a reply, this method just forces
  // acknowledgement of the command.
  MarkReplied(status);
}

StreamSetParamsCommand::StreamSetParamsCommand(
    uint32_t stream_id, uint32_t buffer_bytes, uint32_t period_bytes,
    uint32_t features, uint8_t channels, uint8_t format, uint8_t rate)
    : StreamControlCommand(AudioCommandType::VIRTIO_SND_R_PCM_SET_PARAMS,
                           stream_id),
      buffer_bytes_(buffer_bytes),
      period_bytes_(period_bytes),
      features_(features),
      channels_(channels),
      format_(format),
      rate_(rate) {}

}  // namespace cuttlefish
