// 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();

  bool OnNeedsData(MediaResult res);
  void OnPlayoutComplete(MediaResult res);
  void OnConnectionError(const std::string& connection_name);
  void BeginShutdown();

  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](MediaResult 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)
                    << "\"";
    BeginShutdown();
    return;
  }

  payload_ = resp->body.Pass();

  if (!ReadAndValidateRIFFHeader() ||
      !ReadAndValidateWAVHeader() ||
      !ReadAndValidateDATAHeader()) {
    BeginShutdown();
    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_));

  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->max_frames = USecToFrames(BUF_DEPTH_USEC);
  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),
      [this](MediaResult res) {
        if (res != MediaResult::OK) {
          MOJO_LOG(ERROR) << "Failed to configure audio track (res = "
                          << res << ")";
          BeginShutdown();
        }
      });

  // Grab the rate control interface for our audio renderer.
  audio_track_->GetRateControl(GetProxy(&rate_control_),
      [this](MediaResult res) {
        if (res != MediaResult::OK) {
          MOJO_LOG(ERROR) << "Failed to fetch rate control interface "
                          << "(res = " << res << ")";
          BeginShutdown();
        }
      });

  // Set up our connection error handlers for the various interfaces we are
  // holding on to.  Right now, we make no attempt to recover from a closed
  // connection.  If one of our connections is closed, its time to shut down.
  //
  // 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");
  });

  // TODO(johngro): Once the media pipe adapter (audio_pipe) has been changed to
  // be the owner of the connection error handler on the media_pipe object,
  // remove this.  Use the error handler in the adapter instead.
  media_pipe.set_connection_error_handler([this]() {
    OnConnectionError("media_pipe");
  });

  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_->SetWatermarks(USecToBytes(BUF_HI_WATER_USEC),
                             USecToBytes(BUF_LO_WATER_USEC));
  audio_pipe_->SetSignalCallback(
      [this](MediaResult res) -> bool {
        return 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;
}

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

  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 << ")";
    BeginShutdown();
    return false;
  }

  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...";
        BeginShutdown();
        return false;
      }

      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 << ")";
    BeginShutdown();
    return false;
  }

  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;
  }

  return (payload_len_ != 0);
}

void PlayWAVApp::OnPlayoutComplete(MediaResult res) {
  MOJO_DCHECK(!audio_pipe_->GetPending());
  BeginShutdown();
}

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

// 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 seep 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 spurrious "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::BeginShutdown() {
  if (!shutting_down_) {
    shutting_down_ = true;
    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);
}
