// 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 <algorithm>
#include <cmath>
#include <memory>
#include <string>

#include "base/logging.h"
#include "cobalt/script/sequence.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);

// Delay to check if the media session state is not active.
const base::TimeDelta kMaybeFreezeDelay =
    base::TimeDelta::FromMilliseconds(1500);

// 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(MediaSession* media_session)
    : media_session_(media_session),
      platform_playback_state_(kMediaSessionPlaybackStateNone),
      sequence_number_(0) {
  extension_ = static_cast<const CobaltExtensionMediaSessionApi*>(
      SbSystemGetExtension(kCobaltExtensionMediaSessionName));
  if (extension_) {
    if (strcmp(extension_->name, kCobaltExtensionMediaSessionName) != 0 ||
        extension_->version < 1) {
      LOG(WARNING) << "Wrong MediaSession extension supplied";
      extension_ = nullptr;
    } else if (extension_->RegisterMediaSessionCallbacks != nullptr) {
      extension_->RegisterMediaSessionCallbacks(
          this, &InvokeActionCallback, &UpdatePlatformPlaybackStateCallback);
    }
  }
}

MediaSessionClient::~MediaSessionClient() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // Destroy the platform's MediaSessionClient, if it exists.
  if (extension_ != NULL &&
      extension_->DestroyMediaSessionClientCallback != NULL) {
    extension_->DestroyMediaSessionClientCallback();
  }
}

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::PostDelayedTaskForMaybeFreezeCallback() {
  media_session_->task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MediaSessionClient::RunMaybeFreezeCallback,
                 base::Unretained(this), ++sequence_number_),
      kMaybeFreezeDelay);
}

void MediaSessionClient::UpdatePlatformPlaybackState(
    CobaltExtensionMediaSessionPlaybackState 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_ = ConvertPlaybackState(state);
  if (session_state_.actual_playback_state() != ComputeActualPlaybackState()) {
    UpdateMediaSessionState();
  }

  PostDelayedTaskForMaybeFreezeCallback();
}

void MediaSessionClient::RunMaybeFreezeCallback(int sequence_number) {
  if (sequence_number != sequence_number_) return;

  if (!is_active() && !maybe_freeze_callback_.is_null()) {
    maybe_freeze_callback_.Run();
  }
}

void MediaSessionClient::InvokeActionInternal(
    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details) {
  DCHECK(details->action >= 0 &&
         details->action < kCobaltExtensionMediaSessionActionNumActions);

  // Some fields should only be set for applicable actions.
  DCHECK(details->seek_offset < 0.0 ||
         details->action == kCobaltExtensionMediaSessionActionSeekforward ||
         details->action == kCobaltExtensionMediaSessionActionSeekbackward);
  DCHECK(details->seek_time < 0.0 ||
         details->action == kCobaltExtensionMediaSessionActionSeekto);
  DCHECK(!details->fast_seek ||
         details->action == kCobaltExtensionMediaSessionActionSeekto);

  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(
      ConvertMediaSessionAction(details->action));

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

  std::unique_ptr<MediaSessionActionDetails> script_details =
      ConvertActionDetails(*details);
  it->second->value().Run(*script_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;
    size_t artwork_size = 0;
    if (session_state.has_metadata() &&
        session_state.metadata().value().has_artwork()) {
      artwork_size = session_state.metadata().value().artwork().size();
    }
    std::unique_ptr<CobaltExtensionMediaImage[]> ext_artwork =
        std::unique_ptr<CobaltExtensionMediaImage[]>(
            new CobaltExtensionMediaImage[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.has_position_state = session_state.has_position_state();
    ext_state.actual_playback_state =
        ConvertPlaybackState(session_state.actual_playback_state());
    ConvertMediaSessionActions(session_state.available_actions(),
                               ext_state.available_actions);
    std::string album = "";
    std::string artist = "";
    std::string title = "";

    if (session_state.has_metadata()) {
      const MediaMetadataInit& metadata = session_state.metadata().value();
      album = metadata.album();
      artist = metadata.artist();
      title = metadata.title();
      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_artwork[i] = ext_image;
        }
      }
    }
    CobaltExtensionMediaMetadata ext_metadata = {
        album.c_str(), artist.c_str(), title.c_str(), ext_artwork.get(),
        artwork_size};
    ext_state.metadata = &ext_metadata;

    extension_->OnMediaSessionStateChanged(ext_state);
  }
}

// static
void MediaSessionClient::UpdatePlatformPlaybackStateCallback(
    CobaltExtensionMediaSessionPlaybackState state, void* callback_context) {
  MediaSessionClient* client =
      static_cast<MediaSessionClient*>(callback_context);
  client->UpdatePlatformPlaybackState(state);
}

// static
void MediaSessionClient::InvokeActionCallback(
    CobaltExtensionMediaSessionActionDetails details, void* callback_context) {
  MediaSessionClient* client =
      static_cast<MediaSessionClient*>(callback_context);
  client->InvokeAction(details);
}

CobaltExtensionMediaSessionPlaybackState
MediaSessionClient::ConvertPlaybackState(MediaSessionPlaybackState state) {
  switch (state) {
    case kMediaSessionPlaybackStatePlaying:
      return kCobaltExtensionMediaSessionPlaying;
    case kMediaSessionPlaybackStatePaused:
      return kCobaltExtensionMediaSessionPaused;
    case kMediaSessionPlaybackStateNone:
    default:
      return kCobaltExtensionMediaSessionNone;
  }
}

MediaSessionPlaybackState MediaSessionClient::ConvertPlaybackState(
    CobaltExtensionMediaSessionPlaybackState state) {
  switch (state) {
    case kCobaltExtensionMediaSessionPlaying:
      return kMediaSessionPlaybackStatePlaying;
    case kCobaltExtensionMediaSessionPaused:
      return kMediaSessionPlaybackStatePaused;
    case kCobaltExtensionMediaSessionNone:
    default:
      return kMediaSessionPlaybackStateNone;
  }
}

void MediaSessionClient::ConvertMediaSessionActions(
    const MediaSessionState::AvailableActionsSet& actions,
    bool result[kCobaltExtensionMediaSessionActionNumActions]) {
  for (int i = 0; i < kCobaltExtensionMediaSessionActionNumActions; i++) {
    result[i] = false;
    MediaSessionAction action = static_cast<MediaSessionAction>(i);
    if (actions[action]) {
      result[ConvertMediaSessionAction(action)] = true;
    }
  }
}

std::unique_ptr<MediaSessionActionDetails>
MediaSessionClient::ConvertActionDetails(
    const CobaltExtensionMediaSessionActionDetails& ext_details) {
  std::unique_ptr<MediaSessionActionDetails> details(
      new MediaSessionActionDetails());
  details->set_action(ConvertMediaSessionAction(ext_details.action));
  if (ext_details.seek_offset >= 0.0) {
    details->set_seek_offset(ext_details.seek_offset);
  }
  if (ext_details.seek_time >= 0.0) {
    details->set_seek_time(ext_details.seek_time);
  }
  details->set_fast_seek(ext_details.fast_seek);
  return details;
}

CobaltExtensionMediaSessionAction MediaSessionClient::ConvertMediaSessionAction(
    MediaSessionAction action) {
  switch (action) {
    case kMediaSessionActionPause:
      return kCobaltExtensionMediaSessionActionPause;
    case kMediaSessionActionSeekbackward:
      return kCobaltExtensionMediaSessionActionSeekbackward;
    case kMediaSessionActionPrevioustrack:
      return kCobaltExtensionMediaSessionActionPrevioustrack;
    case kMediaSessionActionNexttrack:
      return kCobaltExtensionMediaSessionActionNexttrack;
    case kMediaSessionActionSeekforward:
      return kCobaltExtensionMediaSessionActionSeekforward;
    case kMediaSessionActionSeekto:
      return kCobaltExtensionMediaSessionActionSeekto;
    case kMediaSessionActionStop:
      return kCobaltExtensionMediaSessionActionStop;
    case kMediaSessionActionPlay:
    default:
      return kCobaltExtensionMediaSessionActionPlay;
  }
}

MediaSessionAction MediaSessionClient::ConvertMediaSessionAction(
    CobaltExtensionMediaSessionAction action) {
  switch (action) {
    case kCobaltExtensionMediaSessionActionPause:
      return kMediaSessionActionPause;
    case kCobaltExtensionMediaSessionActionSeekbackward:
      return kMediaSessionActionSeekbackward;
    case kCobaltExtensionMediaSessionActionPrevioustrack:
      return kMediaSessionActionPrevioustrack;
    case kCobaltExtensionMediaSessionActionNexttrack:
      return kMediaSessionActionNexttrack;
    case kCobaltExtensionMediaSessionActionSeekforward:
      return kMediaSessionActionSeekforward;
    case kCobaltExtensionMediaSessionActionSeekto:
      return kMediaSessionActionSeekto;
    case kCobaltExtensionMediaSessionActionStop:
      return kMediaSessionActionStop;
    case kCobaltExtensionMediaSessionActionPlay:
    default:
      return kMediaSessionActionPlay;
  }
}
}  // namespace media_session
}  // namespace cobalt
