// Copyright 2015 The Chromium 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 <memory>

#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/application_runner.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/utility/run_loop.h"
#include "mojo/services/media/audio/interfaces/audio_server.mojom.h"
#include "mojo/services/media/audio/interfaces/audio_track.mojom.h"
#include "mojo/services/media/common/cpp/circular_buffer_media_pipe_adapter.h"
#include "mojo/services/media/common/cpp/linear_transform.h"
#include "mojo/services/media/common/cpp/local_time.h"
#include "mojo/services/network/interfaces/network_service.mojom.h"
#include "mojo/services/network/interfaces/url_loader.mojom.h"

#define PACKED __attribute__((packed))

static inline constexpr uint32_t make_fourcc(uint8_t a, uint8_t b,
                                             uint8_t c, uint8_t d) {
  return (static_cast<uint32_t>(a) << 24) |
         (static_cast<uint32_t>(b) << 16) |
         (static_cast<uint32_t>(c) << 8)  |
          static_cast<uint32_t>(d);
}

static inline constexpr uint32_t fetch_fourcc(const void* source) {
  return (static_cast<uint32_t>(static_cast<const uint8_t*>(source)[0]) << 24) |
         (static_cast<uint32_t>(static_cast<const uint8_t*>(source)[1]) << 16) |
         (static_cast<uint32_t>(static_cast<const uint8_t*>(source)[2]) << 8) |
          static_cast<uint32_t>(static_cast<const uint8_t*>(source)[3]);
}

namespace mojo {
namespace media {
namespace audio {
namespace examples {

static constexpr const char* TEST_FILE =
  "http://localhost/test_content/piano2.wav";
static constexpr uint32_t BUF_DEPTH_USEC    = 500000;
static constexpr uint32_t BUF_LO_WATER_USEC = 400000;
static constexpr uint32_t BUF_HI_WATER_USEC = 450000;
static constexpr uint32_t CHUNK_SIZE_USEC   = 10000;

class PlayWAVApp : public ApplicationDelegate {
 public:
  ~PlayWAVApp() override { Quit(); }

  // ApplicationDelegate
  void Initialize(ApplicationImpl* app) override;
  void Quit() override;

 private:
  using AudioPipePtr = std::unique_ptr<CircularBufferMediaPipeAdapter>;
  using AudioPacket  = CircularBufferMediaPipeAdapter::MappedPacket;
  using PacketCbk    = MediaPipe::SendPacketCallback;

  // TODO(johngro): endianness!
  struct PACKED RIFFChunkHeader {
    uint32_t  four_cc;
    uint32_t  length;
  };

  struct PACKED WAVHeader {
    uint32_t  wave_four_cc;
    uint32_t  fmt_four_cc;
    uint32_t  fmt_chunk_len;
    uint16_t  format;
    uint16_t  channel_count;
    uint32_t  frame_rate;
    uint32_t  average_byte_rate;
    uint16_t  frame_size;
    uint16_t  bits_per_sample;
  };

  // TODO(johngro): as mentioned before... endianness!
  static constexpr uint32_t RIFF_FOUR_CC = make_fourcc('R', 'I', 'F', 'F');
  static constexpr uint32_t WAVE_FOUR_CC = make_fourcc('W', 'A', 'V', 'E');
  static constexpr uint32_t FMT_FOUR_CC  = make_fourcc('f', 'm', 't', ' ');
  static constexpr uint32_t DATA_FOUR_CC = make_fourcc('d', 'a', 't', 'a');

  static constexpr uint16_t FORMAT_LPCM  = 0x0001;
  static constexpr uint16_t FORMAT_MULAW = 0x0101;
  static constexpr uint16_t FORMAT_ALAW  = 0x0102;
  static constexpr uint16_t FORMAT_ADPCM = 0x0103;

  static const std::set<std::string> VALID_MIME_TYPES;
  static const std::set<uint16_t>    VALID_FRAME_RATES;
  static const std::set<uint16_t>    VALID_BITS_PER_SAMPLES;

  bool BlockingRead(void* buf, uint32_t len);
  void ProcessHTTPResponse(URLResponsePtr resp);

  bool ReadAndValidateRIFFHeader();
  bool ReadAndValidateWAVHeader();
  bool ReadAndValidateDATAHeader();

  void OnNeedsData(MediaResult res);
  void OnPlayoutComplete(MediaPipe::SendResult res);
  void OnConnectionError(const std::string& connection_name);
  void PostShutdown();
  void Shutdown();

  uint32_t USecToFrames(uint32_t usec) {
    uint64_t ret = (static_cast<uint64_t>(usec) * wav_info_.frame_rate)
                 / 1000000;
    MOJO_DCHECK(ret < std::numeric_limits<uint32_t>::max());
    return ret;
  }

  uint32_t USecToBytes(uint32_t usec) {
    uint32_t frames = USecToFrames(usec);

    MOJO_DCHECK(wav_info_.frame_size);
    MOJO_DCHECK(frames <
                std::numeric_limits<uint32_t>::max() / wav_info_.frame_size);

    return frames * wav_info_.frame_size;
  }

  AudioServerPtr               audio_server_;
  AudioTrackPtr                audio_track_;
  AudioPipePtr                 audio_pipe_;
  RateControlPtr               rate_control_;
  AudioPacket                  audio_packet_;
  PacketCbk                    playout_complete_cbk_;
  NetworkServicePtr            network_service_;
  URLLoaderPtr                 url_loader_;
  ScopedDataPipeConsumerHandle payload_;
  uint32_t                     payload_len_;
  RIFFChunkHeader              riff_hdr_;
  WAVHeader                    wav_info_;
  RIFFChunkHeader              data_hdr_;
  bool                         sent_first_packet_ = false;
  bool                         clock_started_     = false;
  bool                         shutting_down_     = false;
};

const std::set<std::string> PlayWAVApp::VALID_MIME_TYPES({
  "audio/x-wav",
  "audio/wav",
});

const std::set<uint16_t> PlayWAVApp::VALID_FRAME_RATES({
  8000, 16000, 24000, 32000, 48000,
  11025, 22050, 44100,
});

const std::set<uint16_t> PlayWAVApp::VALID_BITS_PER_SAMPLES({
  8, 16,
});

void PlayWAVApp::Initialize(ApplicationImpl* app) {
  app->ConnectToService("mojo:audio_server", &audio_server_);
  audio_server_.set_connection_error_handler([this]() {
    OnConnectionError("audio_server");
  });

  app->ConnectToService("mojo:network_service", &network_service_);
  audio_server_.set_connection_error_handler([this]() {
    OnConnectionError("network_service");
  });

  network_service_->CreateURLLoader(GetProxy(&url_loader_));
  url_loader_.set_connection_error_handler([this]() {
    OnConnectionError("url_loader");
  });

  playout_complete_cbk_ = PacketCbk([this](MediaPipe::SendResult res) {
                                      this->OnPlayoutComplete(res);
                                    });

  URLRequestPtr req(URLRequest::New());
  req->url    = TEST_FILE;
  req->method = "GET";

  auto cbk = [this](URLResponsePtr resp) { ProcessHTTPResponse(resp.Pass()); };
  url_loader_->Start(req.Pass(), URLLoader::StartCallback(cbk));
}

void PlayWAVApp::Quit() {
  if (audio_packet_.packet()) {
    MOJO_DCHECK(audio_pipe_);
    audio_pipe_->CancelMediaPacket(&audio_packet_);
  }

  payload_.reset();
  url_loader_.reset();
  network_service_.reset();
  audio_pipe_.reset();
  rate_control_.reset();
  audio_track_.reset();
  audio_server_.reset();
}

bool PlayWAVApp::BlockingRead(void* buf, uint32_t op_len) {
  MojoResult res;
  uint32_t amt;

  while (true) {
    amt = op_len;
    res = ReadDataRaw(payload_.get(), buf, &amt,
                      MOJO_READ_DATA_FLAG_ALL_OR_NONE);

    if ((res == MOJO_RESULT_SHOULD_WAIT) ||
        (res == MOJO_RESULT_OUT_OF_RANGE)) {
      Wait(payload_.get(),
           MOJO_HANDLE_SIGNAL_READABLE,
           MOJO_DEADLINE_INDEFINITE,
           nullptr);
      continue;
    }

    break;
  }

  return ((res == MOJO_RESULT_OK) && (amt == op_len));
}

void PlayWAVApp::ProcessHTTPResponse(URLResponsePtr resp) {
  if (resp->mime_type.is_null() ||
     (VALID_MIME_TYPES.find(resp->mime_type) == VALID_MIME_TYPES.end())) {
    MOJO_LOG(ERROR) << "Bad MimeType \""
                    << (resp->mime_type.is_null() ? "<null>" : resp->mime_type)
                    << "\"";
    Shutdown();
    return;
  }

  payload_ = resp->body.Pass();

  if (!ReadAndValidateRIFFHeader() ||
      !ReadAndValidateWAVHeader() ||
      !ReadAndValidateDATAHeader()) {
    Shutdown();
    return;
  }

  MOJO_LOG(INFO) << "Preparing to play...";
  MOJO_LOG(INFO) << "File : " << TEST_FILE;
  MOJO_LOG(INFO) << "Rate : " << wav_info_.frame_rate;
  MOJO_LOG(INFO) << "Chan : " << wav_info_.channel_count;
  MOJO_LOG(INFO) << "BPS  : " << wav_info_.bits_per_sample;

  // Create the audio sink we will use to play this WAV file and start to
  // configure it.
  audio_server_->CreateTrack(GetProxy(&audio_track_));

  // TODO(johngro): when there is some better diagnostic information made
  // available to us, make sure that we log it so we have some way to proceed
  // with debugging.
  audio_track_.set_connection_error_handler([this]() {
    OnConnectionError("audio_track");
  });

  LinearTransform::Ratio audio_rate(wav_info_.frame_rate, 1);
  LinearTransform::Ratio local_rate(LocalDuration::period::num,
                                    LocalDuration::period::den);
  LinearTransform::Ratio tmp;
  bool success = LinearTransform::Ratio::Compose(audio_rate, local_rate, &tmp);
  MOJO_DCHECK(success);

  AudioTrackConfigurationPtr cfg;
  cfg = AudioTrackConfiguration::New();
  cfg->audio_frame_ratio = tmp.numerator;
  cfg->media_time_ratio  = tmp.denominator;

  LpcmMediaTypeDetailsPtr pcm_cfg = LpcmMediaTypeDetails::New();
  pcm_cfg->sample_format = (wav_info_.bits_per_sample == 8)
                         ? LpcmSampleFormat::UNSIGNED_8
                         : LpcmSampleFormat::SIGNED_16;
  pcm_cfg->channels = wav_info_.channel_count;
  pcm_cfg->frames_per_second = wav_info_.frame_rate;

  cfg->media_type = MediaType::New();
  cfg->media_type->scheme = MediaTypeScheme::LPCM;
  cfg->media_type->details = MediaTypeDetails::New();
  cfg->media_type->details->set_lpcm(pcm_cfg.Pass());

  // Configure the track based on the WAV header information.
  MediaPipePtr media_pipe;
  audio_track_->Configure(cfg.Pass(), GetProxy(&media_pipe));

  // Grab the rate control interface for our audio renderer.
  audio_track_->GetRateControl(GetProxy(&rate_control_));
  rate_control_.set_connection_error_handler([this]() {
    OnConnectionError("rate_control");
  });

  // Set up our media pipe helper, configure its callback and water marks to
  // kick off the playback process.
  audio_pipe_.reset(new CircularBufferMediaPipeAdapter(media_pipe.Pass()));
  audio_pipe_->Init(USecToBytes(BUF_DEPTH_USEC));
  audio_pipe_->SetWatermarks(USecToBytes(BUF_HI_WATER_USEC),
                             USecToBytes(BUF_LO_WATER_USEC));
  audio_pipe_->SetSignalCallback(
  [this](MediaResult res) -> void {
    OnNeedsData(res);
  });
}

bool PlayWAVApp::ReadAndValidateRIFFHeader() {
  // Read and sanity check the top level RIFF header
  if (!BlockingRead(&riff_hdr_, sizeof(riff_hdr_))) {
    MOJO_LOG(ERROR) << "Failed to read top level RIFF header!";
    return false;
  }

  if (fetch_fourcc(&riff_hdr_.four_cc) != RIFF_FOUR_CC) {
    MOJO_LOG(ERROR) << "Missing expected 'RIFF' 4CC "
                    << "(expected 0x " << std::hex << RIFF_FOUR_CC
                    << " got 0x"       << std::hex
                    << fetch_fourcc(&riff_hdr_.four_cc)
                    << ")";
    return false;
  }

  return true;
}

bool PlayWAVApp::ReadAndValidateWAVHeader() {
  // Read the WAVE header along with its required format chunk.
  if (!BlockingRead(&wav_info_, sizeof(wav_info_))) {
    MOJO_LOG(ERROR) << "Failed to read top level WAVE header!";
    return false;
  }

  if (fetch_fourcc(&wav_info_.wave_four_cc) != WAVE_FOUR_CC) {
    MOJO_LOG(ERROR) << "Missing expected 'WAVE' 4CC "
                    << "(expected 0x " << std::hex << WAVE_FOUR_CC
                    << " got 0x"
                    << std::hex << fetch_fourcc(&wav_info_.wave_four_cc)
                    << ")";
    return false;
  }

  if (fetch_fourcc(&wav_info_.fmt_four_cc) != FMT_FOUR_CC) {
    MOJO_LOG(ERROR) << "Missing expected 'fmt ' 4CC "
                    << "(expected 0x " << std::hex << FMT_FOUR_CC
                    << " got 0x"
                    << std::hex << fetch_fourcc(&wav_info_.fmt_four_cc)
                    << ")";
    return false;
  }

  // Sanity check the format of the wave file.  This demo only support a limited
  // subset of the possible formats.
  if (wav_info_.format != FORMAT_LPCM) {
    MOJO_LOG(ERROR) << "Unsupported format (0x"
                    << std::hex << wav_info_.format
                    << ") must be LPCM (0x"
                    << std::hex << FORMAT_LPCM
                    << ")";
    return false;
  }

  if ((wav_info_.channel_count != 1) && (wav_info_.channel_count != 2)) {
    MOJO_LOG(ERROR) << "Unsupported channel count ("
                    << wav_info_.channel_count
                    << ") must be either mono or stereo";
    return false;
  }

  if (VALID_FRAME_RATES.find(wav_info_.frame_rate) == VALID_FRAME_RATES.end()) {
    MOJO_LOG(ERROR) << "Unsupported frame_rate ("
                    << wav_info_.frame_rate << ")";
    return false;
  }

  if (VALID_BITS_PER_SAMPLES.find(wav_info_.bits_per_sample) ==
      VALID_BITS_PER_SAMPLES.end()) {
    MOJO_LOG(ERROR) << "Unsupported bits per sample ("
                    << wav_info_.bits_per_sample << ")";
    return false;
  }

  uint16_t expected_frame_size;
  expected_frame_size = (wav_info_.channel_count * wav_info_.bits_per_sample)
                        >> 3;
  if (wav_info_.frame_size != expected_frame_size) {
    MOJO_LOG(ERROR) << "Frame size sanity check failed.  (expected "
                    << expected_frame_size << " got "
                    << wav_info_.frame_size << ")";
    return false;
  }

  return true;
}

bool PlayWAVApp::ReadAndValidateDATAHeader() {
  // Technically, there could be format specific member of the wave format
  // chunk, or other riff chunks which could come after this, but for this demo,
  // we only handle getting the 'data' chunk at this point.
  if (!BlockingRead(&data_hdr_, sizeof(data_hdr_))) {
    MOJO_LOG(ERROR) << "Failed to read data header!";
    return false;
  }

  if (fetch_fourcc(&data_hdr_.four_cc) != DATA_FOUR_CC) {
    MOJO_LOG(ERROR) << "Missing expected 'data' 4CC "
                    << "(expected 0x " << std::hex << DATA_FOUR_CC
                    << " got 0x"       << std::hex
                    << fetch_fourcc(&data_hdr_.four_cc)
                    << ")";
    return false;
  }

  if ((data_hdr_.length + sizeof(WAVHeader) + sizeof(RIFFChunkHeader))
      != riff_hdr_.length) {
    MOJO_LOG(ERROR) << "Header length sanity check failure ("
                    << data_hdr_.length << " + "
                    << sizeof(WAVHeader) + sizeof(RIFFChunkHeader) << " != "
                    << riff_hdr_.length << ")";
    return false;
  }

  // If the length of the data chunk is not a multiple of the frame size, log a
  // warning and truncate the length.
  uint16_t leftover;
  payload_len_ = data_hdr_.length;
  leftover     = payload_len_ % wav_info_.frame_size;
  if (leftover) {
    MOJO_LOG(WARNING)
      << "Data chunk length (" << payload_len_
      << ") not a multiple of frame size (" << wav_info_.frame_size
      << ")";
    payload_len_ -= leftover;
  }

  return true;
}

void PlayWAVApp::OnNeedsData(MediaResult res) {
  if (res != MediaResult::OK) {
    MOJO_LOG(ERROR) << "Error during playback!  (res = " << res << ")";
    PostShutdown();
    return;
  }

  if (!payload_len_) {
    // If we are just waiting for playout to finish, keep receiving callbacks so
    // we know if something went fatally wrong.
    return;
  }

  uint64_t bytes = USecToBytes(CHUNK_SIZE_USEC);
  if (bytes > payload_len_) {
    bytes = payload_len_;
  }

  res = audio_pipe_->CreateMediaPacket(bytes, false, &audio_packet_);
  if (res != MediaResult::OK) {
    MOJO_LOG(ERROR) << "Failed to create " << bytes << " byte media packet!  "
                    << "(res = " << res << ")";
    PostShutdown();
    return;
  }

  if (!sent_first_packet_) {
    MOJO_DCHECK(audio_packet_.packet());
    audio_packet_.packet()->pts = 0;
    sent_first_packet_ = true;
  }

  for (size_t i = 0; i < AudioPacket::kMaxRegions; ++i) {
    if (audio_packet_.data(i)) {
      MOJO_DCHECK(audio_packet_.length(i));
      MOJO_DCHECK(audio_packet_.length(i) <= payload_len_);

      if (!BlockingRead(audio_packet_.data(i),
                        audio_packet_.length(i))) {
        MOJO_LOG(ERROR) << "Failed to read source, shutting down...";
        PostShutdown();
        return;
      }

      payload_len_ -= audio_packet_.length(i);
    }
  }

  if (payload_len_) {
    res = audio_pipe_->SendMediaPacket(&audio_packet_);
  } else {
    res = audio_pipe_->SendMediaPacket(&audio_packet_, playout_complete_cbk_);
  }

  if (res != MediaResult::OK) {
    MOJO_LOG(ERROR) << "Failed to send media packet!  "
                    << "(res = " << res << ")";
    PostShutdown();
    return;
  }

  if (!clock_started_ && (audio_pipe_->AboveHiWater() || !payload_len_)) {
    LocalTime sched = LocalClock::now() + local_time::from_msec(50);
    rate_control_->SetRateAtTargetTime(1, 1, sched.time_since_epoch().count());
    clock_started_ = true;
  }
}

void PlayWAVApp::OnPlayoutComplete(MediaPipe::SendResult res) {
  MOJO_DCHECK(!audio_pipe_->GetPending());
  audio_pipe_ = nullptr;
  PostShutdown();
}

void PlayWAVApp::OnConnectionError(const std::string& connection_name) {
  if (!shutting_down_) {
    MOJO_LOG(ERROR) << connection_name << " connection closed unexpectedly!";
    PostShutdown();
  }
}

void PlayWAVApp::PostShutdown() {
  if (audio_pipe_) {
    audio_pipe_->ResetSignalCallback();
  }

  mojo::RunLoop::current()->PostDelayedTask([this]() -> void {
    Shutdown();
  }, 0);
}

// TODO(johngro): remove this when we can.  Right now, the proper way to cleanly
// shut down a running mojo application is a bit unclear to me.  Calling
// RunLoop::current()->Quit() seems like the best option, but the run loop does
// not seem to call our application's quit method.  Instead, it starts to close
// all of our connections (triggering all of our connection error handlers we
// have registered on interfaces) before finally destroying our application
// object.
//
// The net result is that we end up spurious "connection closed unexpectedly"
// error messages when we are actually shutting down cleanly.  For now, we
// suppress this by having a shutting_down_ flag and suppressing the error
// message which show up after shutdown has been triggered.  When the proper
// pattern for shutting down an app has been established, come back here and
// remove all this junk.
void PlayWAVApp::Shutdown() {
  Quit();
  RunLoop::current()->Quit();
}

}  // namespace examples
}  // namespace audio
}  // namespace media
}  // namespace mojo

MojoResult MojoMain(MojoHandle app_request) {
  mojo::ApplicationRunner runner(
      std::unique_ptr<mojo::media::audio::examples::PlayWAVApp>(
          new mojo::media::audio::examples::PlayWAVApp()));
  return runner.Run(app_request);
}
