// 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/system/wait.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    = MediaConsumer::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(MediaConsumer::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](MediaConsumer::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.
  MediaConsumerPtr 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(MediaConsumer::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);
}
