// 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 "starboard/android/shared/cobalt/android_media_session_client.h"

#include "base/time/time.h"
#include "cobalt/media_session/media_session_action_details.h"
#include "cobalt/media_session/media_session_client.h"
#include "cobalt/script/sequence.h"
#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/jni_utils.h"
#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/once.h"

namespace starboard {
namespace android {
namespace shared {
namespace cobalt {

using ::cobalt::media_session::MediaImage;
using ::cobalt::media_session::MediaMetadataInit;
using ::cobalt::media_session::MediaSession;
using ::cobalt::media_session::MediaSessionAction;
using ::cobalt::media_session::MediaSessionActionDetails;
using ::cobalt::media_session::MediaSessionClient;
using ::cobalt::media_session::MediaSessionPlaybackState;
using ::cobalt::media_session::MediaSessionState;
using ::cobalt::media_session::kMediaSessionActionPause;
using ::cobalt::media_session::kMediaSessionActionPlay;
using ::cobalt::media_session::kMediaSessionActionSeekto;
using ::cobalt::media_session::kMediaSessionActionSeekbackward;
using ::cobalt::media_session::kMediaSessionActionSeekforward;
using ::cobalt::media_session::kMediaSessionActionStop;
using ::cobalt::media_session::kMediaSessionActionPrevioustrack;
using ::cobalt::media_session::kMediaSessionActionNexttrack;
using ::cobalt::media_session::kMediaSessionPlaybackStateNone;
using ::cobalt::media_session::kMediaSessionPlaybackStatePaused;
using ::cobalt::media_session::kMediaSessionPlaybackStatePlaying;

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

using ::starboard::android::shared::JniEnvExt;
using ::starboard::android::shared::ScopedLocalJavaRef;

namespace {

// These constants are from android.media.session.PlaybackState
const jlong kPlaybackStateActionStop = 1 << 0;
const jlong kPlaybackStateActionPause = 1 << 1;
const jlong kPlaybackStateActionPlay = 1 << 2;
const jlong kPlaybackStateActionRewind = 1 << 3;
const jlong kPlaybackStateActionSkipToPrevious = 1 << 4;
const jlong kPlaybackStateActionSkipToNext = 1 << 5;
const jlong kPlaybackStateActionFastForward = 1 << 6;
const jlong kPlaybackStateActionSetRating = 1 << 7;  // not supported
const jlong kPlaybackStateActionSeekTo = 1 << 8;

// Converts a MediaSessionClient::AvailableActions bitset into
// a android.media.session.PlaybackState jlong bitset.
jlong MediaSessionActionsToPlaybackStateActions(
    const MediaSessionState::AvailableActionsSet& actions) {
  jlong result = 0;
  if (actions[kMediaSessionActionPause]) {
    result |= kPlaybackStateActionPause;
  }
  if (actions[kMediaSessionActionPlay]) {
    result |= kPlaybackStateActionPlay;
  }
  if (actions[kMediaSessionActionSeekbackward]) {
    result |= kPlaybackStateActionRewind;
  }
  if (actions[kMediaSessionActionPrevioustrack]) {
    result |= kPlaybackStateActionSkipToPrevious;
  }
  if (actions[kMediaSessionActionNexttrack]) {
    result |= kPlaybackStateActionSkipToNext;
  }
  if (actions[kMediaSessionActionSeekforward]) {
    result |= kPlaybackStateActionFastForward;
  }
  if (actions[kMediaSessionActionSeekto]) {
    result |= kPlaybackStateActionSeekTo;
  }
  if (actions[kMediaSessionActionStop]) {
    result |= kPlaybackStateActionStop;
  }
  return result;
}

PlaybackState MediaSessionPlaybackStateToPlaybackState(
    MediaSessionPlaybackState in_state) {
  switch (in_state) {
    case kMediaSessionPlaybackStatePlaying:
      return kPlaying;
    case kMediaSessionPlaybackStatePaused:
      return kPaused;
    case kMediaSessionPlaybackStateNone:
      return kNone;
  }
}

MediaSessionAction PlaybackStateActionToMediaSessionAction(jlong action) {
  MediaSessionAction result;
  switch (action) {
    case kPlaybackStateActionPause:
      result = kMediaSessionActionPause;
      break;
    case kPlaybackStateActionPlay:
      result = kMediaSessionActionPlay;
      break;
    case kPlaybackStateActionRewind:
      result = kMediaSessionActionSeekbackward;
      break;
    case kPlaybackStateActionSkipToPrevious:
      result = kMediaSessionActionPrevioustrack;
      break;
    case kPlaybackStateActionSkipToNext:
      result = kMediaSessionActionNexttrack;
      break;
    case kPlaybackStateActionFastForward:
      result = kMediaSessionActionSeekforward;
      break;
    case kPlaybackStateActionSeekTo:
      result = kMediaSessionActionSeekto;
      break;
    case kPlaybackStateActionStop:
      result = kMediaSessionActionStop;
      break;
    default:
      SB_NOTREACHED() << "Unsupported MediaSessionAction 0x"
                      << std::hex << action;
      result = static_cast<MediaSessionAction>(-1);
  }
  return result;
}

MediaSessionPlaybackState PlaybackStateToMediaSessionPlaybackState(
    PlaybackState state) {
  MediaSessionPlaybackState result;
  switch (state) {
    case kPlaying:
      result = kMediaSessionPlaybackStatePlaying;
      break;
    case kPaused:
      result = kMediaSessionPlaybackStatePaused;
      break;
    case kNone:
      result = kMediaSessionPlaybackStateNone;
      break;
    default:
      SB_NOTREACHED() << "Unsupported PlaybackState " << state;
      result = static_cast<MediaSessionPlaybackState>(-1);
  }
  return result;
}

}  // namespace

class AndroidMediaSessionClient : public MediaSessionClient {
  static SbOnceControl once_flag;
  static SbMutex mutex;
  // The last MediaSessionClient to become active, or null.
  // Used to route Java callbacks.
  // In practice, only one MediaSessionClient will become active at a time.
  // Protected by "mutex"
  static AndroidMediaSessionClient* active_client;

  static void OnceInit() { SbMutexCreate(&mutex); }

 public:
  static void NativeInvokeAction(jlong action, jlong seek_ms) {
    SbOnce(&once_flag, OnceInit);
    SbMutexAcquire(&mutex);

    if (active_client != NULL) {
      std::unique_ptr<MediaSessionActionDetails> details(
          new MediaSessionActionDetails());
      details->set_action(PlaybackStateActionToMediaSessionAction(action));
      // CobaltMediaSession.java only sets seek_ms for SeekTo (not ff/rew).
      if (details->action() == kMediaSessionActionSeekto) {
        details->set_seek_time(seek_ms / 1000.0);
      }
      active_client->InvokeAction(std::move(details));
    }

    SbMutexRelease(&mutex);
  }

  static void UpdateActiveSessionPlatformPlaybackState(
      MediaSessionPlaybackState state) {
    SbOnce(&once_flag, OnceInit);
    SbMutexAcquire(&mutex);

    if (active_client != NULL) {
      active_client->UpdatePlatformPlaybackState(state);
    }

    SbMutexRelease(&mutex);
  }

  AndroidMediaSessionClient() {}

  virtual ~AndroidMediaSessionClient() {
    SbOnce(&once_flag, OnceInit);
    SbMutexAcquire(&mutex);
    if (active_client == this) {
      active_client = NULL;
    }
    SbMutexRelease(&mutex);
  }

  void OnMediaSessionStateChanged(
      const MediaSessionState& session_state) override {
    JniEnvExt* env = JniEnvExt::Get();

    jint playback_state = MediaSessionPlaybackStateToPlaybackState(
        session_state.actual_playback_state());

    SbOnce(&once_flag, OnceInit);
    SbMutexAcquire(&mutex);
    if (playback_state != kNone) {
      active_client = this;
    } else if (active_client == this) {
      active_client = NULL;
    }
    SbMutexRelease(&mutex);

    jlong playback_state_actions = MediaSessionActionsToPlaybackStateActions(
        session_state.available_actions());

    ScopedLocalJavaRef<jstring> j_title;
    ScopedLocalJavaRef<jstring> j_artist;
    ScopedLocalJavaRef<jstring> j_album;
    ScopedLocalJavaRef<jobjectArray> j_artwork;

    if (session_state.has_metadata()) {
      const MediaMetadataInit& media_metadata(session_state.metadata().value());

      j_title.Reset(
          env->NewStringStandardUTFOrAbort(media_metadata.title().c_str()));
      j_artist.Reset(
          env->NewStringStandardUTFOrAbort(media_metadata.artist().c_str()));
      j_album.Reset(
          env->NewStringStandardUTFOrAbort(media_metadata.album().c_str()));

      if (media_metadata.has_artwork()) {
        const MediaImageSequence& artwork(media_metadata.artwork());
        ScopedLocalJavaRef<jclass> media_image_class(
            env->FindClassExtOrAbort("dev/cobalt/media/MediaImage"));
        jmethodID media_image_constructor = env->GetMethodID(
            media_image_class.Get(), "<init>",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
        env->AbortOnException();

        j_artwork.Reset(static_cast<jobjectArray>(env->NewObjectArray(
            artwork.size(), media_image_class.Get(), NULL)));
        env->AbortOnException();

        ScopedLocalJavaRef<jstring> j_src;
        ScopedLocalJavaRef<jstring> j_sizes;
        ScopedLocalJavaRef<jstring> j_type;
        for (MediaImageSequence::size_type i = 0; i < artwork.size(); i++) {
          const MediaImage& media_image(artwork.at(i));
          j_src.Reset(
              env->NewStringStandardUTFOrAbort(media_image.src().c_str()));
          j_sizes.Reset(
              env->NewStringStandardUTFOrAbort(media_image.sizes().c_str()));
          j_type.Reset(
              env->NewStringStandardUTFOrAbort(media_image.type().c_str()));

          ScopedLocalJavaRef<jobject> j_media_image(
              env->NewObject(media_image_class.Get(), media_image_constructor,
                             j_src.Get(), j_sizes.Get(), j_type.Get()));

          env->SetObjectArrayElement(j_artwork.Get(), i, j_media_image.Get());
        }
      }
    }

    jlong duration = session_state.duration();
    // Set duration to negative if duration is unknown or infinite, as with live
    // playback.
    // https://developer.android.com/reference/android/support/v4/media/MediaMetadataCompat#METADATA_KEY_DURATION
    if (duration == kSbTimeMax) {
      duration = -1;
    }

    env->CallStarboardVoidMethodOrAbort(
        "updateMediaSession",
        "(IJJFLjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
        "[Ldev/cobalt/media/MediaImage;J)V",
        playback_state, playback_state_actions,
        session_state.current_playback_position() / kSbTimeMillisecond,
        static_cast<jfloat>(session_state.actual_playback_rate()),
        j_title.Get(), j_artist.Get(), j_album.Get(), j_artwork.Get(),
        duration);
  }
};

SbOnceControl AndroidMediaSessionClient::once_flag = SB_ONCE_INITIALIZER;
SbMutex AndroidMediaSessionClient::mutex;
AndroidMediaSessionClient* AndroidMediaSessionClient::active_client = NULL;

void UpdateActiveSessionPlatformPlaybackState(PlaybackState state) {
  MediaSessionPlaybackState media_session_state =
      PlaybackStateToMediaSessionPlaybackState(state);

  AndroidMediaSessionClient::UpdateActiveSessionPlatformPlaybackState(
      media_session_state);
}

}  // namespace cobalt
}  // namespace shared
}  // namespace android
}  // namespace starboard

using starboard::android::shared::cobalt::AndroidMediaSessionClient;

extern "C" SB_EXPORT_PLATFORM
void Java_dev_cobalt_media_CobaltMediaSession_nativeInvokeAction(
    JNIEnv* env,
    jclass unused_clazz,
    jlong action,
    jlong seek_ms) {
  AndroidMediaSessionClient::NativeInvokeAction(action, seek_ms);
}

namespace cobalt {
namespace media_session {

// static
std::unique_ptr<MediaSessionClient> MediaSessionClient::Create() {
  return std::unique_ptr<MediaSessionClient>(new AndroidMediaSessionClient());
}

}  // namespace media_session
}  // namespace cobalt
