// Copyright 2017 The Cobalt Authors. 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 "cobalt/media_session/media_session_client.h"
#include "cobalt/script/sequence.h"

#include <algorithm>
#include <cmath>
#include <memory>

#include "base/logging.h"
#include "starboard/time.h"

using MediaImageSequence = ::cobalt::script::Sequence<MediaImage>;

namespace cobalt {
namespace media_session {

namespace {

// Delay to re-query position state after an action has been invoked.
const base::TimeDelta kUpdateDelay = base::TimeDelta::FromMilliseconds(250);

// Guess the media position state for the media session.
void GuessMediaPositionState(MediaSessionState* session_state,
    const media::WebMediaPlayer** guess_player,
    const media::WebMediaPlayer* current_player) {
  // Assume the player with the biggest video size is the one controlled by the
  // media session. This isn't perfect, so it's best that the web app set the
  // media position state explicitly.
  if (*guess_player == nullptr ||
      (*guess_player)->GetNaturalSize().GetArea() <
      current_player->GetNaturalSize().GetArea()) {
    *guess_player = current_player;

    MediaPositionState position_state;
    float duration = (*guess_player)->GetDuration();
    if (std::isfinite(duration)) {
      position_state.set_duration(duration);
    } else if (std::isinf(duration)) {
      position_state.set_duration(kSbTimeMax);
    } else {
      position_state.set_duration(0.0);
    }
    position_state.set_playback_rate((*guess_player)->GetPlaybackRate());
    position_state.set_position((*guess_player)->GetCurrentTime());

    *session_state = MediaSessionState(
        session_state->metadata(),
        SbTimeGetMonotonicNow(),
        position_state,
        session_state->actual_playback_state(),
        session_state->available_actions());
  }
}

}  // namespace

MediaSessionClient::MediaSessionClient(
    scoped_refptr<MediaSession> media_session)
    : media_session_(media_session),
      platform_playback_state_(kMediaSessionPlaybackStateNone) {
#if SB_API_VERSION < 11
  extension_ = nullptr;
#else
  extension_ = static_cast<const CobaltExtensionMediaSessionApi*>(
      SbSystemGetExtension(kCobaltExtensionMediaSessionName));
  if (extension_) {
    if (SbStringCompareAll(extension_->name,
                           kCobaltExtensionMediaSessionName) != 0 ||
        extension_->version < 1) {
      LOG(WARNING) << "Wrong MediaSession extension supplied";
      extension_ = nullptr;
    }
  }
#endif
}

MediaSessionClient::~MediaSessionClient() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // Prevent any outstanding MediaSession::OnChanged tasks from calling this.
  media_session_->media_session_client_ = nullptr;
}

void MediaSessionClient::SetMediaPlayerFactory(
    const media::WebMediaPlayerFactory* factory) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  media_player_factory_ = factory;
}

MediaSessionPlaybackState MediaSessionClient::ComputeActualPlaybackState()
    const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // Per https://wicg.github.io/mediasession/#guessed-playback-state
  // - If the "declared playback state" is "playing", then return "playing"
  // - Otherwise, return the guessed playback state
  MediaSessionPlaybackState declared_state;
  declared_state = media_session_->playback_state();
  if (declared_state == kMediaSessionPlaybackStatePlaying) {
    return kMediaSessionPlaybackStatePlaying;
  }

  if (platform_playback_state_ == kMediaSessionPlaybackStatePlaying) {
    // "...guessed playback state is playing if any of them is
    // potentially playing and not muted..."
    return kMediaSessionPlaybackStatePlaying;
  }

  // It's not super clear what to do when the declared state or the
  // active media session state is kPaused or kNone

  if (declared_state == kMediaSessionPlaybackStatePaused) {
    return kMediaSessionPlaybackStatePaused;
  }

  return kMediaSessionPlaybackStateNone;
}

MediaSessionState::AvailableActionsSet
MediaSessionClient::ComputeAvailableActions() const {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // "Available actions" are determined based on active media session
  // and supported media session actions.
  // Note for cobalt, there's only one window/tab so there's only one
  // "active media session"
  // https://wicg.github.io/mediasession/#actions-model
  //
  // Note that this is essentially the "media session actions update algorithm"
  // inverted.
  MediaSessionState::AvailableActionsSet result =
      MediaSessionState::AvailableActionsSet();

  for (MediaSession::ActionMap::iterator it =
           media_session_->action_map_.begin();
       it != media_session_->action_map_.end(); ++it) {
    result[it->first] = true;
  }

  switch (ComputeActualPlaybackState()) {
    case kMediaSessionPlaybackStatePlaying:
      // "If the active media session’s actual playback state is playing, remove
      // play from available actions."
      result[kMediaSessionActionPlay] = false;
      break;
    case kMediaSessionPlaybackStateNone:
      // Not defined in the spec: disable Seekbackward, Seekforward, SeekTo, &
      // Stop when no media is playing.
      result[kMediaSessionActionSeekbackward] = false;
      result[kMediaSessionActionSeekforward] = false;
      result[kMediaSessionActionSeekto] = false;
      result[kMediaSessionActionStop] = false;
    // Fall-through intended (None case falls through to Paused case).
    case kMediaSessionPlaybackStatePaused:
      // "Otherwise, remove pause from available actions."
      result[kMediaSessionActionPause] = false;
      break;
  }

  return result;
}

void MediaSessionClient::UpdatePlatformPlaybackState(
    MediaSessionPlaybackState state) {
  DCHECK(media_session_->task_runner_);
  if (!media_session_->task_runner_->BelongsToCurrentThread()) {
    media_session_->task_runner_->PostTask(
        FROM_HERE, base::Bind(&MediaSessionClient::UpdatePlatformPlaybackState,
                              base::Unretained(this), state));
    return;
  }

  platform_playback_state_ = state;
  if (session_state_.actual_playback_state() != ComputeActualPlaybackState()) {
    UpdateMediaSessionState();
  }
}

void MediaSessionClient::InvokeActionInternal(
    std::unique_ptr<MediaSessionActionDetails> details) {
  DCHECK(details->has_action());

  // Some fields should only be set for applicable actions.
  DCHECK(!details->has_seek_offset() ||
         details->action() == kMediaSessionActionSeekforward ||
         details->action() == kMediaSessionActionSeekbackward);
  DCHECK(!details->has_seek_time() ||
         details->action() == kMediaSessionActionSeekto);
  DCHECK(!details->has_fast_seek() ||
         details->action() == kMediaSessionActionSeekto);

  // Seek times/offsets are non-negative, even for seeking backwards.
  DCHECK(!details->has_seek_time() || details->seek_time() >= 0.0);
  DCHECK(!details->has_seek_offset() || details->seek_offset() >= 0.0);

  DCHECK(media_session_->task_runner_);
  if (!media_session_->task_runner_->BelongsToCurrentThread()) {
    media_session_->task_runner_->PostTask(
        FROM_HERE, base::Bind(&MediaSessionClient::InvokeActionInternal,
                              base::Unretained(this), base::Passed(&details)));
    return;
  }

  MediaSession::ActionMap::iterator it =
      media_session_->action_map_.find(details->action());

  if (it == media_session_->action_map_.end()) {
    return;
  }

  it->second->value().Run(*details);

  // Queue a session update to reflect the effects of the action.
  if (!media_session_->media_position_state_) {
    media_session_->MaybeQueueChangeTask(kUpdateDelay);
  }
}

void MediaSessionClient::UpdateMediaSessionState() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  scoped_refptr<MediaMetadata> session_metadata(media_session_->metadata());
  base::Optional<MediaMetadataInit> metadata;
  if (session_metadata) {
    metadata.emplace();
    metadata->set_title(session_metadata->title());
    metadata->set_artist(session_metadata->artist());
    metadata->set_album(session_metadata->album());
    metadata->set_artwork(session_metadata->artwork());
  }

  session_state_ = MediaSessionState(
      metadata,
      media_session_->last_position_updated_time_,
      media_session_->media_position_state_,
      ComputeActualPlaybackState(),
      ComputeAvailableActions());

  // Compute the media position state if it's not set in the media session.
  if (!media_session_->media_position_state_ && media_player_factory_) {
    const media::WebMediaPlayer* player = nullptr;
    media_player_factory_->EnumerateWebMediaPlayers(
        base::BindRepeating(&GuessMediaPositionState,
                            &session_state_, &player));

    // The media duration may be reported as 0 when seeking. Re-query the
    // media session state after a delay.
    if (session_state_.actual_playback_state() ==
            kMediaSessionPlaybackStatePlaying &&
        session_state_.duration() == 0) {
      media_session_->MaybeQueueChangeTask(kUpdateDelay);
    }
  }

  OnMediaSessionStateChanged(session_state_);
}

void MediaSessionClient::OnMediaSessionStateChanged(
    const MediaSessionState& session_state) {
  if (extension_ && extension_->version >= 1) {
    CobaltExtensionMediaSessionState ext_state;
    CobaltExtensionMediaMetadata ext_metadata = {0};
    size_t artwork_size = 0;
    if (session_state.has_metadata() &&
        session_state.metadata().value().has_artwork()) {
      artwork_size = session_state.metadata().value().artwork().size();
    }
    ext_metadata.artwork_count = artwork_size;

    ext_state.duration = session_state.duration();
    ext_state.actual_playback_rate = session_state.actual_playback_rate();
    ext_state.current_playback_position =
        session_state.current_playback_position();
    ext_state.actual_playback_state =
        ConvertPlaybackState(session_state.actual_playback_state());
    ConvertMediaSessionActions(session_state.available_actions(),
                               ext_state.available_actions);

    if (session_state.has_metadata()) {
      const MediaMetadataInit& metadata = session_state.metadata().value();
      ext_metadata.album = metadata.album().c_str();
      ext_metadata.artist = metadata.artist().c_str();
      ext_metadata.title = metadata.title().c_str();
      if (artwork_size > 0) {
        const MediaImageSequence& artwork(metadata.artwork());
        for (MediaImageSequence::size_type i = 0; i < artwork_size; i++) {
          const MediaImage& media_image(artwork.at(i));
          CobaltExtensionMediaImage ext_image;
          ext_image.src = media_image.src().c_str();
          ext_image.size = media_image.sizes().c_str();
          ext_image.type = media_image.type().c_str();
          ext_metadata.artwork[i] = ext_image;
        }
      }
      ext_state.metadata = ext_metadata;
    }

    extension_->OnMediaSessionStateChanged(ext_state);
  }
}

CobaltExtensionPlaybackState MediaSessionClient::ConvertPlaybackState(
    MediaSessionPlaybackState in_state) {
  switch (in_state) {
    case kMediaSessionPlaybackStatePlaying:
      return CobaltExtensionPlaybackState::kCobaltExtensionPlaying;
    case kMediaSessionPlaybackStatePaused:
      return CobaltExtensionPlaybackState::kCobaltExtensionPaused;
    case kMediaSessionPlaybackStateNone:
    default:
      return CobaltExtensionPlaybackState::kCobaltExtensionNone;
  }
}

void MediaSessionClient::ConvertMediaSessionActions(
    const MediaSessionState::AvailableActionsSet& actions,
    bool result[kCobaltExtensionMediaSessionActionNumActions]) {
  for (int i = 0; i < kCobaltExtensionMediaSessionActionNumActions; i++) {
    result[i] = false;
  }
  if (actions[kMediaSessionActionPause]) {
    result[kCobaltExtensionMediaSessionActionPause] = true;
  }
  if (actions[kMediaSessionActionPlay]) {
    result[kCobaltExtensionMediaSessionActionPlay] = true;
  }
  if (actions[kMediaSessionActionSeekbackward]) {
    result[kCobaltExtensionMediaSessionActionSeekbackward] = true;
  }
  if (actions[kMediaSessionActionPrevioustrack]) {
    result[kCobaltExtensionMediaSessionActionPrevioustrack] = true;
  }
  if (actions[kMediaSessionActionNexttrack]) {
    result[kCobaltExtensionMediaSessionActionNexttrack] = true;
  }
  if (actions[kMediaSessionActionSeekforward]) {
    result[kCobaltExtensionMediaSessionActionSeekforward] = true;
  }
  if (actions[kMediaSessionActionSeekto]) {
    result[kCobaltExtensionMediaSessionActionSeekto] = true;
  }
  if (actions[kMediaSessionActionStop]) {
    result[kCobaltExtensionMediaSessionActionStop] = true;
  }
}

}  // namespace media_session
}  // namespace cobalt
