// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/media/sounds/soundplayer/sound.h"

namespace soundplayer {
namespace {

constexpr uint64_t kNanosPerSecond = 1000000000;
const char kVmoName[] = "soundplayer decoded sound";

bool operator==(const fuchsia::media::AudioStreamType& lhs,
                const fuchsia::media::AudioStreamType& rhs) {
  return lhs.sample_format == rhs.sample_format && lhs.channels == rhs.channels &&
         lhs.frames_per_second == rhs.frames_per_second;
}

}  // namespace

Sound::Sound(zx::vmo vmo, uint64_t size, fuchsia::media::AudioStreamType stream_type)
    : vmo_(std::move(vmo)), size_(size), stream_type_(std::move(stream_type)) {
  FX_CHECK(vmo_.get_size(&vmo_size_) == ZX_OK);
}

const zx::vmo& Sound::LockForRead() {
  FX_DCHECK(lock_count_ >= 0);

  if (++lock_count_ == 1) {
    ApplyLockForRead();
  }

  return vmo();
}

const zx::vmo& Sound::LockForWrite() {
  FX_DCHECK(lock_count_ >= 0);

  if (++lock_count_ == 1) {
    ApplyLockForWrite();
  }

  return vmo();
}

void Sound::Unlock() {
  FX_DCHECK(lock_count_ > 0);

  if (--lock_count_ == 0) {
    Removelock();
  }
}

zx::duration Sound::duration() const {
  return zx::nsec(kNanosPerSecond * size_) / stream_type_.channels / sizeof(int16_t) /
         stream_type_.frames_per_second;
}

uint64_t Sound::frame_count() const { return size_ / frame_size(); }

uint32_t Sound::frame_size() const { return sample_size() * stream_type_.channels; }

uint32_t Sound::sample_size() const {
  switch (stream_type_.sample_format) {
    case fuchsia::media::AudioSampleFormat::UNSIGNED_8:
      return sizeof(uint8_t);
    case fuchsia::media::AudioSampleFormat::SIGNED_16:
      return sizeof(int16_t);
    case fuchsia::media::AudioSampleFormat::SIGNED_24_IN_32:
      return sizeof(int32_t);
    case fuchsia::media::AudioSampleFormat::FLOAT:
      return sizeof(float);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// DiscardableSound definitions.

void DiscardableSound::ApplyLockForRead() {
  FX_DCHECK(vmo());

  zx_vmo_lock_state lock_state;
  zx_status_t status =
      vmo().op_range(ZX_VMO_OP_LOCK, 0, vmo_size(), &lock_state, sizeof(lock_state));
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Failed to lock vmo for read";
  }

  if (lock_state.discarded_size > 0) {
    Restore();
  }
}

void DiscardableSound::ApplyLockForWrite() {
  FX_DCHECK(vmo());

  zx_vmo_lock_state lock_state;
  zx_status_t status =
      vmo().op_range(ZX_VMO_OP_LOCK, 0, vmo_size(), &lock_state, sizeof(lock_state));
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Failed to lock vmo for write";
  }
}

void DiscardableSound::Removelock() {
  FX_DCHECK(vmo());

  zx_status_t status = vmo().op_range(ZX_VMO_OP_UNLOCK, 0, vmo_size(), nullptr, 0);
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Failed to unlock vmo";
  }
}

zx_status_t DiscardableSound::SetSize(size_t size_arg) {
  if (vmo()) {
    return size() == size_arg ? ZX_OK : ZX_ERR_INTERNAL;
  }

  zx_status_t status = zx::vmo::create(size_arg, ZX_VMO_DISCARDABLE, &vmo());
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Failed to create vmo";
    return status;
  }

  status = vmo().set_property(ZX_PROP_NAME, kVmoName, strlen(kVmoName));
  if (status != ZX_OK) {
    FX_PLOGS(WARNING, status) << "Failed to set vmo name";
  }

  uint64_t vmo_size;
  FX_CHECK(vmo().get_size(&vmo_size) == ZX_OK);

  Sound::SetSize(size_arg, vmo_size);
  return ZX_OK;
}

zx_status_t DiscardableSound::SetStreamType(fuchsia::media::AudioStreamType stream_type_arg) {
  if (stream_type().frames_per_second != 0) {
    return stream_type() == stream_type_arg ? ZX_OK : ZX_ERR_INTERNAL;
  }

  Sound::SetStreamType(std::move(stream_type_arg));
  return ZX_OK;
}

void DiscardableSound::Restore() {
  if (restore_callback_) {
    restore_callback_();
  }
}

}  // namespace soundplayer
