// 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 "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"

#include "starboard/audio_sink.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/drm/drm_system_internal.h"
#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
#include "starboard/shared/starboard/player/filter/player_components.h"
#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
#include "starboard/time.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {

namespace {

typedef MediaTimeProviderImpl::MonotonicSystemTimeProvider
    MonotonicSystemTimeProvider;

// TODO: Make this configurable inside SbPlayerCreate().
const SbTimeMonotonic kUpdateInterval = 5 * kSbTimeMillisecond;

class MonotonicSystemTimeProviderImpl : public MonotonicSystemTimeProvider {
  SbTimeMonotonic GetMonotonicNow() const override {
    return SbTimeGetMonotonicNow();
  }
};

}  // namespace

FilterBasedPlayerWorkerHandler::FilterBasedPlayerWorkerHandler(
    SbMediaVideoCodec video_codec,
    SbMediaAudioCodec audio_codec,
    SbDrmSystem drm_system,
    const SbMediaAudioHeader* audio_header,
    SbPlayerOutputMode output_mode,
    SbDecodeTargetGraphicsContextProvider* provider)
    : video_codec_(video_codec),
      audio_codec_(audio_codec),
      drm_system_(drm_system),
      output_mode_(output_mode),
      decode_target_graphics_context_provider_(provider) {
  if (audio_codec != kSbMediaAudioCodecNone) {
    audio_header_ = *audio_header;

#if SB_API_VERSION >= 6
    if (audio_header_.audio_specific_config_size > 0) {
      audio_specific_config_.reset(
          new int8_t[audio_header_.audio_specific_config_size]);
      SbMemoryCopy(audio_specific_config_.get(),
                   audio_header->audio_specific_config,
                   audio_header->audio_specific_config_size);
      audio_header_.audio_specific_config = audio_specific_config_.get();
    }
#endif  // SB_API_VERSION >= 6
  }

  update_job_ = std::bind(&FilterBasedPlayerWorkerHandler::Update, this);
  bounds_ = PlayerWorker::Bounds();
}

bool FilterBasedPlayerWorkerHandler::IsPunchoutMode() const {
  return (output_mode_ == kSbPlayerOutputModePunchOut);
}

bool FilterBasedPlayerWorkerHandler::Init(
    PlayerWorker* player_worker,
    JobQueue* job_queue,
    SbPlayer player,
    UpdateMediaTimeCB update_media_time_cb,
    GetPlayerStateCB get_player_state_cb,
    UpdatePlayerStateCB update_player_state_cb
#if SB_HAS(PLAYER_ERROR_MESSAGE)
    ,
    UpdatePlayerErrorCB update_player_error_cb
#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)
    ) {
  // This function should only be called once.
  SB_DCHECK(player_worker_ == NULL);

  // All parameters have to be valid.
  SB_DCHECK(player_worker);
  SB_DCHECK(job_queue);
  SB_DCHECK(job_queue->BelongsToCurrentThread());
  SB_DCHECK(SbPlayerIsValid(player));
  SB_DCHECK(update_media_time_cb);
  SB_DCHECK(get_player_state_cb);
  SB_DCHECK(update_player_state_cb);

  player_worker_ = player_worker;
  job_queue_ = job_queue;
  player_ = player;
  update_media_time_cb_ = update_media_time_cb;
  get_player_state_cb_ = get_player_state_cb;
  update_player_state_cb_ = update_player_state_cb;
#if SB_HAS(PLAYER_ERROR_MESSAGE)
  update_player_error_cb_ = update_player_error_cb;
#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)

  scoped_ptr<PlayerComponents> player_components = PlayerComponents::Create();
  SB_DCHECK(player_components);

  if (audio_codec_ != kSbMediaAudioCodecNone) {
    // TODO: This is not ideal as we should really handle the creation failure
    // of audio sink inside the audio renderer to give the renderer a chance to
    // resample the decoded audio.
    const int audio_channels = audio_header_.number_of_channels;
    if (audio_channels > SbAudioSinkGetMaxChannels()) {
      return false;
    }

    PlayerComponents::AudioParameters audio_parameters = {
        audio_codec_, audio_header_, drm_system_, job_queue_};

    audio_renderer_ = player_components->CreateAudioRenderer(audio_parameters);
    SB_DCHECK(audio_renderer_);
    if (audio_renderer_) {
      audio_renderer_->SetPlaybackRate(playback_rate_);
      audio_renderer_->SetVolume(volume_);
      audio_renderer_->Initialize(
          std::bind(&FilterBasedPlayerWorkerHandler::OnError, this));
    }
  } else {
    media_time_provider_impl_.reset(
        new MediaTimeProviderImpl(scoped_ptr<MonotonicSystemTimeProvider>(
            new MonotonicSystemTimeProviderImpl)));
    media_time_provider_impl_->SetPlaybackRate(playback_rate_);
  }

  PlayerComponents::VideoParameters video_parameters = {
      player_,    video_codec_, drm_system_,
      job_queue_, output_mode_, decode_target_graphics_context_provider_};

  ::starboard::ScopedLock lock(video_renderer_existence_mutex_);

  auto media_time_provider = GetMediaTimeProvider();
  SB_DCHECK(media_time_provider);

  video_renderer_ = player_components->CreateVideoRenderer(video_parameters,
                                                           media_time_provider);
  SB_DCHECK(video_renderer_);
  if (video_renderer_) {
    video_renderer_->Initialize(
        std::bind(&FilterBasedPlayerWorkerHandler::OnError, this));
  }

  update_job_token_ = job_queue_->Schedule(update_job_, kUpdateInterval);

  return true;
}

bool FilterBasedPlayerWorkerHandler::Seek(SbTime seek_to_time, int ticket) {
  SB_UNREFERENCED_PARAMETER(ticket);
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (!GetMediaTimeProvider() || !video_renderer_) {
    return false;
  }

  if (seek_to_time < 0) {
    SB_DLOG(ERROR) << "Try to seek to negative timestamp " << seek_to_time;
    seek_to_time = 0;
  }

  GetMediaTimeProvider()->Pause();
  video_renderer_->Seek(seek_to_time);
  GetMediaTimeProvider()->Seek(seek_to_time);
  return true;
}

bool FilterBasedPlayerWorkerHandler::WriteSample(
    const scoped_refptr<InputBuffer>& input_buffer,
    bool* written) {
  SB_DCHECK(input_buffer);
  SB_DCHECK(job_queue_->BelongsToCurrentThread());
  SB_DCHECK(written != NULL);

  if (input_buffer->sample_type() == kSbMediaTypeAudio) {
    if (!audio_renderer_) {
      return false;
    }

    *written = true;

    if (audio_renderer_->IsEndOfStreamWritten()) {
      SB_LOG(WARNING) << "Try to write audio sample after EOS is reached";
    } else {
      if (!audio_renderer_->CanAcceptMoreData()) {
        *written = false;
        return true;
      }

      if (input_buffer->drm_info()) {
        if (!SbDrmSystemIsValid(drm_system_)) {
          return false;
        }
        SbDrmSystemPrivate::DecryptStatus decrypt_status =
            drm_system_->Decrypt(input_buffer);
        if (decrypt_status == SbDrmSystemPrivate::kRetry) {
          *written = false;
          return true;
        }
        if (decrypt_status == SbDrmSystemPrivate::kFailure) {
          *written = false;
          return false;
        }
      }
      audio_renderer_->WriteSample(input_buffer);
    }
  } else {
    SB_DCHECK(input_buffer->sample_type() == kSbMediaTypeVideo);

    if (!video_renderer_) {
      return false;
    }

    *written = true;

    if (video_renderer_->IsEndOfStreamWritten()) {
      SB_LOG(WARNING) << "Try to write video sample after EOS is reached";
    } else {
      if (!video_renderer_->CanAcceptMoreData()) {
        *written = false;
        return true;
      }
      if (input_buffer->drm_info()) {
        if (!SbDrmSystemIsValid(drm_system_)) {
          return false;
        }
        SbDrmSystemPrivate::DecryptStatus decrypt_status =
            drm_system_->Decrypt(input_buffer);
        if (decrypt_status == SbDrmSystemPrivate::kRetry) {
          *written = false;
          return true;
        }
        if (decrypt_status == SbDrmSystemPrivate::kFailure) {
          *written = false;
          return false;
        }
      }
      if (media_time_provider_impl_) {
        media_time_provider_impl_->UpdateVideoDuration(
            input_buffer->timestamp());
      }
      video_renderer_->WriteSample(input_buffer);
    }
  }

  return true;
}

bool FilterBasedPlayerWorkerHandler::WriteEndOfStream(SbMediaType sample_type) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (sample_type == kSbMediaTypeAudio) {
    if (!audio_renderer_) {
      return false;
    }
    if (audio_renderer_->IsEndOfStreamWritten()) {
      SB_LOG(WARNING) << "Try to write audio EOS after EOS is enqueued";
    } else {
      SB_LOG(INFO) << "Audio EOS enqueued";
      audio_renderer_->WriteEndOfStream();
    }
  } else {
    if (!video_renderer_) {
      return false;
    }
    if (video_renderer_->IsEndOfStreamWritten()) {
      SB_LOG(WARNING) << "Try to write video EOS after EOS is enqueued";
    } else {
      SB_LOG(INFO) << "Video EOS enqueued";
      if (media_time_provider_impl_) {
        media_time_provider_impl_->VideoEndOfStreamReached();
      }
      video_renderer_->WriteEndOfStream();
    }
  }

  return true;
}

bool FilterBasedPlayerWorkerHandler::SetPause(bool pause) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (!GetMediaTimeProvider()) {
    return false;
  }

  paused_ = pause;

  if (pause) {
    GetMediaTimeProvider()->Pause();
    SB_DLOG(INFO) << "Playback paused.";
  } else {
    GetMediaTimeProvider()->Play();
    SB_DLOG(INFO) << "Playback started.";
  }

  return true;
}

bool FilterBasedPlayerWorkerHandler::SetPlaybackRate(double playback_rate) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  playback_rate_ = playback_rate;

  if (!GetMediaTimeProvider()) {
    return false;
  }

  GetMediaTimeProvider()->SetPlaybackRate(playback_rate_);
  return true;
}

void FilterBasedPlayerWorkerHandler::SetVolume(double volume) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  volume_ = volume;
  if (audio_renderer_) {
    audio_renderer_->SetVolume(volume_);
  }
}

bool FilterBasedPlayerWorkerHandler::SetBounds(
    const PlayerWorker::Bounds& bounds) {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (SbMemoryCompare(&bounds_, &bounds, sizeof(bounds_)) != 0) {
    bounds_ = bounds;
    if (video_renderer_) {
      // TODO: Force a frame update
      video_renderer_->SetBounds(bounds.z_index, bounds.x, bounds.y,
                                 bounds.width, bounds.height);
    }
  }

  return true;
}

void FilterBasedPlayerWorkerHandler::OnError() {
  if (!job_queue_->BelongsToCurrentThread()) {
    job_queue_->Schedule(
        std::bind(&FilterBasedPlayerWorkerHandler::OnError, this));
    return;
  }

#if SB_HAS(PLAYER_ERROR_MESSAGE)
  if (update_player_error_cb_) {
    (*player_worker_.*
     update_player_error_cb_)("FilterBasedPlayerWorkerHandler error.");
  }
#else   // SB_HAS(PLAYER_ERROR_MESSAGE)
  (*player_worker_.*update_player_state_cb_)(kSbPlayerStateError);
#endif  // SB_HAS(PLAYER_ERROR_MESSAGE)
}

// TODO: This should be driven by callbacks instead polling.
void FilterBasedPlayerWorkerHandler::Update() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  if (!GetMediaTimeProvider() || !video_renderer_) {
    return;
  }

  if ((*player_worker_.*get_player_state_cb_)() == kSbPlayerStatePrerolling) {
    bool audio_seek_in_progress =
        audio_renderer_ && audio_renderer_->IsSeekingInProgress();
    if (!audio_seek_in_progress &&
        !video_renderer_->UpdateAndRetrieveIsSeekingInProgress()) {
      (*player_worker_.*update_player_state_cb_)(kSbPlayerStatePresenting);
      if (!paused_) {
        GetMediaTimeProvider()->Play();
      }
    }
  }

  if ((*player_worker_.*get_player_state_cb_)() == kSbPlayerStatePresenting) {
    bool is_audio_playing;
    bool is_audio_eos_played;
    GetMediaTimeProvider()->GetCurrentMediaTime(&is_audio_playing,
                                                &is_audio_eos_played);
    if (is_audio_eos_played && video_renderer_->IsEndOfStreamPlayed()) {
      (*player_worker_.*update_player_state_cb_)(kSbPlayerStateEndOfStream);
    }

    player_worker_->UpdateDroppedVideoFrames(
        video_renderer_->GetDroppedFrames());
    bool is_playing;
    bool is_eos_played;
    (*player_worker_.*
     update_media_time_cb_)(GetMediaTimeProvider()->GetCurrentMediaTime(
        &is_playing, &is_eos_played));
  }

  update_job_token_ = job_queue_->Schedule(update_job_, kUpdateInterval);
}

void FilterBasedPlayerWorkerHandler::Stop() {
  SB_DCHECK(job_queue_->BelongsToCurrentThread());

  job_queue_->RemoveJobByToken(update_job_token_);

  scoped_ptr<VideoRenderer> video_renderer;
  {
    // Set |video_renderer_| to null with the lock, but we actually destroy
    // it outside of the lock.  This is because the VideoRenderer destructor
    // may post a task to destroy the SbDecodeTarget to the same thread that
    // might call GetCurrentDecodeTarget(), which would try to take this lock.
    ::starboard::ScopedLock lock(video_renderer_existence_mutex_);
    video_renderer = video_renderer_.Pass();
  }
  video_renderer.reset();
  audio_renderer_.reset();
  media_time_provider_impl_.reset();
}

SbDecodeTarget FilterBasedPlayerWorkerHandler::GetCurrentDecodeTarget() {
  ::starboard::ScopedLock lock(video_renderer_existence_mutex_);
  return video_renderer_ ? video_renderer_->GetCurrentDecodeTarget()
                         : kSbDecodeTargetInvalid;
}

MediaTimeProvider* FilterBasedPlayerWorkerHandler::GetMediaTimeProvider()
    const {
  if (audio_renderer_) {
    return audio_renderer_.get();
  }
  return media_time_provider_impl_.get();
}

}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
