/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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 "media/audio/null_audio_streamer.h"

#include <algorithm>

#include "media/audio/audio_parameters.h"
#include "media/mp4/aac.h"

namespace media {

NullAudioStreamer::NullAudioStreamer()
    : null_streamer_thread_("Null Audio Streamer") {
  null_streamer_thread_.Start();
  null_streamer_thread_.message_loop()->PostTask(
      FROM_HERE, base::Bind(&NullAudioStreamer::StartNullStreamer,
                            base::Unretained(this)));
}

NullAudioStreamer::~NullAudioStreamer() {
  null_streamer_thread_.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&NullAudioStreamer::StopNullStreamer, base::Unretained(this)));
  null_streamer_thread_.Stop();
}

ShellAudioStreamer::Config NullAudioStreamer::GetConfig() const {
  // Reasonable looking settings.
  const uint32 initial_rebuffering_frames_per_channel =
      mp4::AAC::kFramesPerAccessUnit * 32;
  const uint32 sink_buffer_size_in_frames_per_channel =
      initial_rebuffering_frames_per_channel * 8;
  const uint32 max_hardware_channels = 2;

  return Config(Config::INTERLEAVED, initial_rebuffering_frames_per_channel,
                sink_buffer_size_in_frames_per_channel, max_hardware_channels,
                sizeof(float) /* bytes_per_sample */);
}

bool NullAudioStreamer::AddStream(ShellAudioStream* stream) {
  base::AutoLock auto_lock(streams_lock_);
  streams_.insert(std::make_pair(stream, NullAudioStream()));
  return true;
}

void NullAudioStreamer::RemoveStream(ShellAudioStream* stream) {
  base::AutoLock auto_lock(streams_lock_);
  DLOG(INFO) << "Remove";
  streams_.erase(stream);
}

bool NullAudioStreamer::HasStream(ShellAudioStream* stream) const {
  base::AutoLock auto_lock(streams_lock_);
  return streams_.find(stream) != streams_.end();
}

void NullAudioStreamer::StartNullStreamer() {
  last_run_time_ = base::Time::Now();
  advance_streams_timer_.emplace();
  advance_streams_timer_->Start(
      FROM_HERE, base::TimeDelta::FromMilliseconds(10),
      base::Bind(&NullAudioStreamer::AdvanceStreams, base::Unretained(this)));
}

void NullAudioStreamer::StopNullStreamer() {
  advance_streams_timer_->Stop();
  advance_streams_timer_ = base::nullopt;
}

void NullAudioStreamer::AdvanceStreams() {
  base::Time now = base::Time::Now();
  base::TimeDelta time_played = now - last_run_time_;
  last_run_time_ = now;

  base::AutoLock auto_lock(streams_lock_);
  for (NullAudioStreamMap::iterator it = streams_.begin(); it != streams_.end();
       ++it) {
    PullFrames(it->first, time_played, &it->second);
  }
}

void NullAudioStreamer::PullFrames(ShellAudioStream* stream,
                                   base::TimeDelta time_played,
                                   NullAudioStream* null_stream) {
  // Calculate how many frames were consumed.
  int sample_rate = stream->GetAudioParameters().sample_rate();
  uint32 frames_played = sample_rate * time_played.InSecondsF();
  frames_played = std::min(frames_played, null_stream->total_available_frames);
  if (!stream->PauseRequested()) {
    stream->ConsumeFrames(frames_played);
  }
  // Pull more frames.
  stream->PullFrames(NULL, &null_stream->total_available_frames);
}

}  // namespace media
