package de.christinecoenen.code.zapp.app.player;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.analytics.AnalyticsListener;
import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.upstream.HttpDataSource;

import java.io.IOException;

import de.christinecoenen.code.zapp.R;
import io.reactivex.subjects.BehaviorSubject;
import timber.log.Timber;

/**
 * Transforms player events from exo player into RXJava observables.
 */
class PlayerEventHandler implements AnalyticsListener {

	private final BehaviorSubject<Boolean> isBufferingSource = BehaviorSubject.create();
	private final BehaviorSubject<Boolean> isIdleSource = BehaviorSubject.create();
	private final BehaviorSubject<Integer> errorResourceIdSource = BehaviorSubject.create();
	private final BehaviorSubject<Boolean> shouldHoldWakelockSource = BehaviorSubject.create();

	BehaviorSubject<Boolean> isBuffering() {
		return isBufferingSource;
	}

	BehaviorSubject<Boolean> isIdle() {
		return isIdleSource;
	}

	BehaviorSubject<Integer> getErrorResourceId() {
		return errorResourceIdSource;
	}

	/**
	 * @return emits true when the player is playing or buffering and false
	 * if it is idle, paused or stopped
	 */
	BehaviorSubject<Boolean> getShouldHoldWakelock() {
		return shouldHoldWakelockSource;
	}

	@Override
	public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int playbackState) {
		boolean isBuffering = playbackState == Player.STATE_BUFFERING;
		isBufferingSource.onNext(isBuffering);

		boolean isReady = playbackState == Player.STATE_IDLE;
		isIdleSource.onNext(isReady);

		boolean shouldHoldWakelock = playWhenReady &&
			(playbackState == Player.STATE_BUFFERING || playbackState == Player.STATE_READY);
		shouldHoldWakelockSource.onNext(shouldHoldWakelock);
	}

	@Override
	public void onPlayerError(EventTime eventTime, ExoPlaybackException error) {
		int errorMessageResourceId = R.string.error_stream_unknown;

		switch (error.type) {
			case ExoPlaybackException.TYPE_SOURCE:
				Timber.e(error, "exo player error TYPE_SOURCE");
				errorMessageResourceId = R.string.error_stream_io;
				break;
			case ExoPlaybackException.TYPE_RENDERER:
				Timber.e(error, "exo player error TYPE_RENDERER");
				errorMessageResourceId = R.string.error_stream_unsupported;
				break;
			case ExoPlaybackException.TYPE_UNEXPECTED:
				Timber.e(error, "exo player error TYPE_UNEXPECTED");
				break;
		}

		errorResourceIdSource.onNext(errorMessageResourceId);
	}

	@Override
	public void onLoadError(EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) {
		if (wasCanceled) {
			return;
		}

		Timber.e(error, "exo player onLoadError");

		if (error instanceof HttpDataSource.HttpDataSourceException) {
			errorResourceIdSource.onNext(R.string.error_stream_io);
		} else {
			errorResourceIdSource.onNext(R.string.error_stream_unknown);
		}
	}
}

@@ -929,101 +929,8 @@
 e();
-%0A%09private final BehaviorSubject%3CBoolean%3E shouldHoldWakelockSource = BehaviorSubject.create();
 %0A%0A%09B
@@ -1154,219 +1154,8 @@
 %09%7D%0A%0A
-%09/**%0A%09 * @return emits true when the player is playing or buffering and false%0A%09 * if it is idle, paused or stopped%0A%09 */%0A%09BehaviorSubject%3CBoolean%3E getShouldHoldWakelock() %7B%0A%09%09return shouldHoldWakelockSource;%0A%09%7D%0A%0A
 %09@Ov
@@ -1180,18 +1180,20 @@
 d onPlay
-er
+back
 StateCha
@@ -1221,31 +1221,8 @@
 ime,
- boolean playWhenReady,
  int
@@ -1437,197 +1437,8 @@
 dy);
-%0A%0A%09%09boolean shouldHoldWakelock = playWhenReady &&%0A%09%09%09(playbackState == Player.STATE_BUFFERING %7C%7C playbackState == Player.STATE_READY);%0A%09%09shouldHoldWakelockSource.onNext(shouldHoldWakelock);
 %0A%09%7D%0A
@@ -2063,16 +2063,217 @@
 %09break;%0A
+%09%09%09case ExoPlaybackException.TYPE_OUT_OF_MEMORY:%0A%09%09%09case ExoPlaybackException.TYPE_REMOTE:%0A%09%09%09case ExoPlaybackException.TYPE_TIMEOUT:%0A%09%09%09%09Timber.e(error, %22exo player error %25s%22, error.type);%0A%09%09%09%09break;%0A
 %09%09%7D%0A%0A%09%09e

Remove deprecated and unused code in PlayerEventHandler