// 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.

package dev.cobalt.media;

import static dev.cobalt.media.Log.TAG;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.AudioAttributes;
import android.media.AudioAttributes.Builder;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.view.WindowManager;
import androidx.annotation.RequiresApi;
import dev.cobalt.util.Holder;
import dev.cobalt.util.Log;

/**
 * Cobalt MediaSession glue, as well as collection of state and logic to switch on/off Android OS
 * features used in media playback, such as audio focus, "KEEP_SCREEN_ON" mode, and "visible
 * behind".
 */
public class CobaltMediaSession
    implements AudioManager.OnAudioFocusChangeListener, ArtworkLoader.Callback {

  // We do handle transport controls and set this flag on all API levels, even though it's
  // deprecated and unnecessary on API 26+.
  @SuppressWarnings("deprecation")
  private static final int MEDIA_SESSION_FLAG_HANDLES_TRANSPORT_CONTROLS =
      MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS;

  private AudioFocusRequest audioFocusRequest;

  interface UpdateVolumeListener {
    /** Called when there is a change in audio focus. */
    void onUpdateVolume(float gain);
  }

  /**
   * When losing audio focus with the option of ducking, we reduce the volume to 10%. This arbitrary
   * number is what YouTube Android Player infrastructure uses.
   */
  private static final float AUDIO_FOCUS_DUCK_LEVEL = 0.1f;

  private final Handler mainHandler = new Handler(Looper.getMainLooper());

  private final Context context;
  private final Holder<Activity> activityHolder;

  private final UpdateVolumeListener volumeListener;
  private final ArtworkLoader artworkLoader;
  private MediaSessionCompat mediaSession;

  // We re-use the builder to hold onto the most recent playback state.
  private PlaybackStateCompat.Builder playbackStateBuilder = new PlaybackStateCompat.Builder();

  // Duplicated in starboard/android/shared/android_media_session_client.h
  // PlaybackStateCompat
  private static final int PLAYBACK_STATE_PLAYING = 0;
  private static final int PLAYBACK_STATE_PAUSED = 1;
  private static final int PLAYBACK_STATE_NONE = 2;
  private static final String[] PLAYBACK_STATE_NAME = {"playing", "paused", "none"};

  // Accessed on the main looper thread only.
  private int currentPlaybackState = PLAYBACK_STATE_NONE;
  private boolean transientPause = false;
  private boolean suspended = true;
  private boolean explicitUserActionRequired = false;

  /** LifecycleCallback to notify listeners when |mediaSession| becomes active or inactive. */
  public interface LifecycleCallback {
    void onMediaSessionLifecycle(boolean isActive, MediaSessionCompat.Token token);
  }

  private LifecycleCallback lifecycleCallback = null;

  /** We use the MediaMetadata to hold onto the most recent metadata and add artwork later. */
  public class MediaMetadata {
    public String title = "";
    public String artist = "";
    public String album = "";
    public Bitmap artwork = null;
    public long duration = (long) 0.0;

    public void SetMetadata(
        String title, String artist, String album, Bitmap artwork, long duration) {
      this.title = title;
      this.artist = artist;
      this.album = album;
      this.artwork = artwork;
      this.duration = duration;
    }
  }

  private MediaMetadata metadata = new MediaMetadata();

  public CobaltMediaSession(
      Context context, Holder<Activity> activityHolder, UpdateVolumeListener volumeListener) {
    this.context = context;
    this.activityHolder = activityHolder;

    this.volumeListener = volumeListener;
    artworkLoader = new ArtworkLoader(this);
    setMediaSession();
  }

  public boolean isActive() {
    if (this.mediaSession == null) {
      return false;
    } else {
      return this.mediaSession.isActive();
    }
  }

  public void setLifecycleCallback(LifecycleCallback lifecycleCallback) {
    this.lifecycleCallback = lifecycleCallback;
    if (lifecycleCallback != null && this.mediaSession != null) {
      lifecycleCallback.onMediaSessionLifecycle(
          this.mediaSession.isActive(), this.mediaSession.getSessionToken());
    }
  }

  private void setMediaSession() {
    Log.i(TAG, "MediaSession new");
    if (mediaSession == null) {
      mediaSession = new MediaSessionCompat(context, TAG);
      mediaSession.setFlags(MEDIA_SESSION_FLAG_HANDLES_TRANSPORT_CONTROLS);
      mediaSession.setCallback(
          new MediaSessionCompat.Callback() {
            @Override
            public void onFastForward() {
              Log.i(TAG, "MediaSession action: FAST FORWARD");
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_FAST_FORWARD);
            }

            @Override
            public void onPause() {
              Log.i(TAG, "MediaSession action: PAUSE");
              nativeInvokeAction(PlaybackStateCompat.ACTION_PAUSE);
            }

            @Override
            public void onPlay() {
              Log.i(TAG, "MediaSession action: PLAY");
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_PLAY);
            }

            @Override
            public void onRewind() {
              Log.i(TAG, "MediaSession action: REWIND");
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_REWIND);
            }

            @Override
            public void onSkipToNext() {
              Log.i(TAG, "MediaSession action: SKIP NEXT");
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_SKIP_TO_NEXT);
            }

            @Override
            public void onSkipToPrevious() {
              Log.i(TAG, "MediaSession action: SKIP PREVIOUS");
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS);
            }

            @Override
            public void onSeekTo(long pos) {
              Log.i(TAG, "MediaSession action: SEEK " + pos);
              explicitUserActionRequired = false;
              nativeInvokeAction(PlaybackStateCompat.ACTION_SEEK_TO, pos);
            }

            @Override
            public void onStop() {
              Log.i(TAG, "MediaSession action: STOP");
              nativeInvokeAction(PlaybackStateCompat.ACTION_STOP);
            }
          });
    }
    // |metadataBuilder| may still have no fields at this point, yielding empty metadata.
    MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder();
    mediaSession.setMetadata(metadataBuilder.build());
    // |playbackStateBuilder| may still have no fields at this point.
    mediaSession.setPlaybackState(playbackStateBuilder.build());
  }

  private static void checkMainLooperThread() {
    if (Looper.getMainLooper() != Looper.myLooper()) {
      throw new RuntimeException("Must be on main thread");
    }
  }

  /**
   * Sets system media resources active or not according to whether media is playing. The concept of
   * "media focus" encapsulates wake lock, audio focus and active media session so that all three
   * are set together to stay coherent as playback state changes. This is idempotent as it may be
   * called multiple times during the course of a media session.
   */
  private void configureMediaFocus(int playbackState) {
    checkMainLooperThread();
    if (transientPause && playbackState == PLAYBACK_STATE_PAUSED) {
      Log.i(TAG, "Media focus: paused (transient)");
      // Don't release media focus while transiently paused, otherwise we won't get audiofocus back
      // when the transient condition ends and we would leave playback paused.
      return;
    }
    Log.i(TAG, "Media focus: " + PLAYBACK_STATE_NAME[playbackState]);
    wakeLock(playbackState == PLAYBACK_STATE_PLAYING);
    audioFocus(playbackState == PLAYBACK_STATE_PLAYING);

    boolean activating = playbackState != PLAYBACK_STATE_NONE;
    boolean deactivating = playbackState == PLAYBACK_STATE_NONE;
    if (mediaSession != null) {
      activating = activating && !mediaSession.isActive();
      deactivating = deactivating && mediaSession.isActive();
    }
    if (activating) {
      // Resuming or new playbacks land here.
      setMediaSession();
    }
    if (mediaSession == null) {
      Log.i(TAG, "MediaSession already released");
      return;
    }
    mediaSession.setActive(playbackState != PLAYBACK_STATE_NONE);
    if (lifecycleCallback != null) {
      lifecycleCallback.onMediaSessionLifecycle(
          this.mediaSession.isActive(), this.mediaSession.getSessionToken());
    }
    if (deactivating) {
      // Suspending lands here.
      Log.i(TAG, "MediaSession release");
      mediaSession.release();
      mediaSession = null;
    }
  }

  private void wakeLock(boolean lock) {
    Activity activity = activityHolder.get();
    if (activity == null) {
      return;
    }
    if (lock) {
      activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    } else {
      activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }
  }

  private void audioFocus(boolean focus) {
    if (focus) {
      int res;
      if (Build.VERSION.SDK_INT < 26) {
        res = requestAudioFocus();
      } else {
        res = requestAudioFocusV26();
      }
      // This shouldn't happen, but pause playback to be nice if it does.
      if (res != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        Log.w(TAG, "Audiofocus action: PAUSE (not granted)");
        nativeInvokeAction(PlaybackStateCompat.ACTION_PAUSE);
      }
    } else {
      if (Build.VERSION.SDK_INT < 26) {
        abandonAudioFocus();
      } else {
        abandonAudioFocusV26();
      }
    }
  }

  @SuppressWarnings("deprecation")
  private int requestAudioFocus() {
    return getAudioManager()
        .requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
  }

  @RequiresApi(26)
  private int requestAudioFocusV26() {
    if (audioFocusRequest == null) {
      AudioAttributes audioAttributes =
          new Builder().setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
      audioFocusRequest =
          new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
              .setOnAudioFocusChangeListener(this)
              .setAudioAttributes(audioAttributes)
              .build();
    }
    return getAudioManager().requestAudioFocus(audioFocusRequest);
  }

  @SuppressWarnings("deprecation")
  private void abandonAudioFocus() {
    getAudioManager().abandonAudioFocus(this);
  }

  @RequiresApi(26)
  private void abandonAudioFocusV26() {
    if (audioFocusRequest != null) {
      getAudioManager().abandonAudioFocusRequest(audioFocusRequest);
    }
  }

  /** AudioManager.OnAudioFocusChangeListener implementation. */
  @Override
  public void onAudioFocusChange(int focusChange) {
    String logExtra = "";
    switch (focusChange) {
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
        logExtra = " (transient)";
        // fall through
      case AudioManager.AUDIOFOCUS_LOSS:
        Log.i(TAG, "Audiofocus loss" + logExtra);
        if (currentPlaybackState == PLAYBACK_STATE_PLAYING) {
          Log.i(TAG, "Audiofocus action: PAUSE");
          nativeInvokeAction(PlaybackStateCompat.ACTION_PAUSE);
        }
        break;
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
        Log.i(TAG, "Audiofocus duck");
        // Lower the volume, keep current play state.
        // Starting with API 26 the system does automatic ducking without calling our listener,
        // but we still need this for API < 26.
        volumeListener.onUpdateVolume(AUDIO_FOCUS_DUCK_LEVEL);
        break;
      case AudioManager.AUDIOFOCUS_GAIN:
        Log.i(TAG, "Audiofocus gain");
        // The app has been granted audio focus (again). Raise volume to normal,
        // restart playback if necessary.
        volumeListener.onUpdateVolume(1.0f);
        if (transientPause && currentPlaybackState == PLAYBACK_STATE_PAUSED) {
          Log.i(TAG, "Audiofocus action: PLAY");
          nativeInvokeAction(PlaybackStateCompat.ACTION_PLAY);
        }
        break;
      default: // fall out
    }

    // Keep track of whether we're currently paused because of a transient loss of audiofocus.
    transientPause = (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
    // To restart playback after permanent loss, the user must take an explicit action.
    // See: https://developer.android.com/guide/topics/media-apps/audio-focus
    explicitUserActionRequired = (focusChange == AudioManager.AUDIOFOCUS_LOSS);
  }

  private AudioManager getAudioManager() {
    return (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
  }

  public void resume() {
    mainHandler.post(
        new Runnable() {
          @Override
          public void run() {
            resumeInternal();
          }
        });
  }

  private void resumeInternal() {
    checkMainLooperThread();
    suspended = false;
    // Undoing what may have been done in suspendInternal().
    configureMediaFocus(currentPlaybackState);
  }

  public void suspend() {
    if (Looper.getMainLooper() == Looper.myLooper()) {
      suspendInternal();
    } else {
      mainHandler.post(
          new Runnable() {
            @Override
            public void run() {
              suspendInternal();
            }
          });
    }
  }

  private void suspendInternal() {
    checkMainLooperThread();
    suspended = true;

    // We generally believe the HTML5 app playback state as the source of truth for configuring
    // media focus since only it can know about a momentary pause between videos in a playlist, or
    // other autoplay scenario when we should keep media focus. However, when suspending, any
    // active SbPlayer is destroyed and we release media focus, even if the HTML5 app still thinks
    // it's in a playing state. We'll configure it again in resumeInternal() and the HTML5 app will
    // be none the wiser.
    playbackStateBuilder.setState(
        currentPlaybackState,
        PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN,
        currentPlaybackState == PLAYBACK_STATE_PLAYING ? 1.0f : 0.0f);
    configureMediaFocus(PLAYBACK_STATE_NONE);
  }

  private static void nativeInvokeAction(long action) {
    nativeInvokeAction(action, 0);
  }

  private static native void nativeInvokeAction(long action, long seekMs);

  public void updateMediaSession(
      final int playbackState,
      final long actions,
      final long positionMs,
      final float speed,
      final String title,
      final String artist,
      final String album,
      final MediaImage[] artwork,
      final long duration) {
    mainHandler.post(
        new Runnable() {
          @Override
          public void run() {
            updateMediaSessionInternal(
                playbackState, actions, positionMs, speed, title, artist, album, artwork, duration);
          }
        });
  }

  /** Called on main looper thread when media session changes. */
  private void updateMediaSessionInternal(
      int playbackState,
      long actions,
      long positionMs,
      float speed,
      String title,
      String artist,
      String album,
      MediaImage[] artwork,
      final long duration) {
    checkMainLooperThread();

    boolean hasStateChange = this.currentPlaybackState != playbackState;
    // Always keep track of what the HTML5 app thinks the playback state is so we can configure the
    // media focus correctly, either immediately or when resuming from being suspended.
    this.currentPlaybackState = playbackState;

    // Don't update anything while suspended.
    if (suspended) {
      Log.i(TAG, "Playback state change while suspended: " + PLAYBACK_STATE_NAME[playbackState]);
      return;
    }

    if (hasStateChange) {
      if (playbackState == PLAYBACK_STATE_PLAYING) {
        // We don't want to request media focus if |explicitUserActionRequired| is true when we
        // don't have window focus. Ideally, we should recognize user action to re-request audio
        // focus if |explicitUserActionRequired| is true. Currently we're not able to recognize
        // it. But if we don't have window focus, we know the user is not interacting with our app
        // and we should not request media focus.
        if (!explicitUserActionRequired
            || (activityHolder.get() != null && activityHolder.get().hasWindowFocus())) {
          explicitUserActionRequired = false;
          configureMediaFocus(playbackState);
        } else {
          Log.w(TAG, "Audiofocus action: PAUSE (explicit user action required)");
          nativeInvokeAction(PlaybackStateCompat.ACTION_PAUSE);
        }
      } else {
        // It's fine to abandon media focus anytime.
        configureMediaFocus(playbackState);
      }
    }

    // Ignore updates to the MediaSession metadata if playback is stopped.
    if (playbackState == PLAYBACK_STATE_NONE || mediaSession == null) {
      return;
    }

    int androidPlaybackState;
    String stateName;
    switch (playbackState) {
      case PLAYBACK_STATE_PLAYING:
        androidPlaybackState = PlaybackStateCompat.STATE_PLAYING;
        stateName = "PLAYING";
        break;
      case PLAYBACK_STATE_PAUSED:
        androidPlaybackState = PlaybackStateCompat.STATE_PAUSED;
        stateName = "PAUSED";
        break;
      case PLAYBACK_STATE_NONE:
      default:
        androidPlaybackState = PlaybackStateCompat.STATE_NONE;
        stateName = "NONE";
        break;
    }

    Log.i(
        TAG,
        String.format(
            "MediaSession state: %s, position: %d ms, speed: %f x, duration: %d ms",
            stateName, positionMs, speed, duration));

    playbackStateBuilder =
        new PlaybackStateCompat.Builder()
            .setActions(actions)
            .setState(androidPlaybackState, positionMs, speed);
    mediaSession.setPlaybackState(playbackStateBuilder.build());

    // Let metadata hold onto the most recent metadata and add artwork later.
    metadata.SetMetadata(title, artist, album, artworkLoader.getOrLoadArtwork(artwork), duration);

    // Update the metadata as soon as we can - even before artwork is loaded.
    updateMetadata(false);
  }

  private void updateMetadata(boolean resetMetadataWithEmptyBuilder) {
    if (mediaSession == null) {
      return;
    }

    MediaMetadataCompat.Builder metadataBuilder = new MediaMetadataCompat.Builder();
    // Reset the metadata to make sure the artwork update correctly.
    if (resetMetadataWithEmptyBuilder) mediaSession.setMetadata(metadataBuilder.build());

    metadataBuilder
        .putString(MediaMetadataCompat.METADATA_KEY_TITLE, metadata.title)
        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, metadata.artist)
        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, metadata.album)
        .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, metadata.artwork)
        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, metadata.duration);

    // Set mediaSession's metadata to update the "Now Playing Card".
    mediaSession.setMetadata(metadataBuilder.build());
  }

  @Override
  public void onArtworkLoaded(Bitmap bitmap) {
    metadata.artwork = bitmap;
    // Update artwork when it is ready to use.
    updateMetadata(true);
  }
}
