package com.castlabs.sdk.mux_demo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.castlabs.analytics.AnalyticsMetaData;
import com.castlabs.android.SdkConsts;
import com.castlabs.android.drm.Drm;
import com.castlabs.android.drm.DrmTodayConfiguration;
import com.castlabs.android.player.PlayerConfig;
import com.castlabs.android.player.TrickplayConfiguration;
import com.castlabs.sdk.ima.ImaAdRequest;
import com.castlabs.sdk.mux.MuxPlugin;
import com.mux.stats.sdk.core.CustomOptions;
import com.mux.stats.sdk.core.model.CustomData;
import com.mux.stats.sdk.core.model.CustomerData;
import com.mux.stats.sdk.core.model.CustomerPlayerData;
import com.mux.stats.sdk.core.model.CustomerVideoData;
import com.mux.stats.sdk.core.model.CustomerViewData;

import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

	public static final String INTENT_PLAYLIST = "INTENT_PLAYLIST";
	private Demo[] DEMOS = new Demo[]{
			new Demo("Simple Clear Playback", "Plays an unencrypted stream",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "TOS Simple")
							.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
							.get()),

			new Demo("Simple Clear Playback - No Autoplay", "Plays an unencrypted stream without autoplay",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "TOS No Autoplay")
							.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
							.put(SdkConsts.INTENT_START_PLAYING, false)
							.get()),

			new Demo("DASH Live Clear Playback", "Plays an unencrypted live DASH stream",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "LiveDASH")
							.put(SdkConsts.INTENT_URL, "http://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd")
							.get()),

			new Demo("Simple Clear Playback - IMA Ads", "Plays an unencrypted stream with IMA ads; pre, mid, post",
				SimplePlaybackDemo.class,
				new BundleBuilder(false, "TOS IMA")
					.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
					.put(SdkConsts.INTENT_ADVERTS_DATA, new ImaAdRequest("https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=").toAdRequest())
					.get()),

			new Demo("Simple Clear Playback, offset", "Starts with 30 sec offset",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "TOS With offset")
							.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
							.put(SdkConsts.INTENT_POSITION_TO_PLAY, 30_000_000L)
							.get()),

			new Demo("Simple Clear Playback, session on play", "Starts in paused state, creates analytics upon user play",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "TOS Session on play")
							.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
							.put(SdkConsts.INTENT_START_PLAYING, false)
							.put(SdkConsts.INTENT_ANALYTICS_SESSION_TYPE, SdkConsts.ANALYTICS_SESSION_TYPE_PLAY)
							.get()),

			new Demo("Single Controller Playlist demo", "Creates a playlist with 3 items; protected BBB, clear Livesim, protected TOS. This demo uses the SingleControllerPlaylist.",
				ConcatenatingPlaybackDemo.class,
				new BundleBuilder()
					.put(INTENT_PLAYLIST,
						new PlayerConfig[]{
							new PlayerConfig.Builder("https://demo.cf.castlabs.com/media/bbb_abr/Manifest.mpd")
								.drmConfiguration(new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_PRODUCTION,
									"purchase",
									"default",
									"client_qa",
									"BBB_TEST",
									Drm.BestAvailable
								).get())
								.analyticsMetaData(MuxPlugin.createMetadata(false, "BBB", createCustomerData("Big Buck Bunny"), new CustomOptions(), null))
								.get(),
							new PlayerConfig.Builder("http://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd")
								.analyticsMetaData(MuxPlugin.createMetadata(false, "livesim", createCustomerData("LiveSim"), new CustomOptions(), null))
								.get(),
							new PlayerConfig.Builder("https://demo.cf.castlabs.com/media/shows/tos/Manifest.mpd")
								.drmConfiguration(new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									"tos_next_gen_demo",
									Drm.Widevine
								).get())
								.analyticsMetaData(MuxPlugin.createMetadata(false, "TOS2", createCustomerData("Tears of Steel 2"), new CustomOptions(), null))
								.get(),
						}
					)
					.get()),

			new Demo("Multiple Controller Playlist demo", "Creates a playlist with 3 items; TOS Clear, BBB Drm, TOS Widevine. This demo uses the MultiControllerPlaylist.",
					PlaylistPlaybackDemo.class,
					new BundleBuilder(false, "Multiple Controller Playlist demo")
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_PLAY_BACKGROUND_KEY, false)
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_BACK_PLAYERS_KEY, 1)
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_FORWARD_PLAYERS_KEY, 1)
							.put(PlaylistPlaybackDemo.INTENT_JUST_ENABLE_ANALYTICS_FOR_CURRENT_ITEM, true)
							.put(INTENT_PLAYLIST,
									new PlayerConfig[]{
											new PlayerConfig.Builder(new BundleBuilder(false, "Playlist Asset 1")
													.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
													.get())
													.get(),
											new PlayerConfig.Builder(new BundleBuilder(false, "Playlist Asset 2")
													.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/bbb_abr/Manifest.mpd")
													.get())
													.drmConfiguration(new DrmTodayConfiguration.Builder(
															DrmTodayConfiguration.DRMTODAY_PRODUCTION,
															"purchase",
															"default",
															"client_qa",
															"BBB_TEST",
															Drm.BestAvailable
													).get())
													.get(),
											new PlayerConfig.Builder(new BundleBuilder(false, "Playlist Asset 3")
													.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/DASH/DEMO.mpd")
													.get())
													.drmConfiguration(new DrmTodayConfiguration.Builder(
															DrmTodayConfiguration.DRMTODAY_STAGING,
															"purchase",
															"sessionId",
															"six",
															"dasheverywhere_demo",
															Drm.Widevine
													).get())
													.get(),
									}
							)
							.get()),

			new Demo("Multiple Controller Playlist - Broken Clip and Movie", "Creates a playlist with 1 broken short clip and a movie.",
					PlaylistPlaybackDemo.class,
					new BundleBuilder(false, "Multiple Controller Playlist - Broken Clip and Movie")
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_PLAY_BACKGROUND_KEY, true)
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_BACK_PLAYERS_KEY, 1)
							.put(PlaylistPlaybackDemo.INTENT_PLAYLIST_FORWARD_PLAYERS_KEY, 1)
							.put(PlaylistPlaybackDemo.INTENT_JUST_ENABLE_ANALYTICS_FOR_CURRENT_ITEM, true)
							.put(INTENT_PLAYLIST,
									new PlayerConfig[] {
											new PlayerConfig.Builder(new BundleBuilder(false, "Broken Clip")
													.put(SdkConsts.INTENT_URL, "http://demo.castlabs.com/media/client_test_cases/ASDK-655/Manifest.mpd")
													.get())
													.get(),
											new PlayerConfig.Builder(new BundleBuilder(false, "Movie")
													.put(SdkConsts.INTENT_URL, "http://demo.cf.castlabs.com/media/TOS/abr/Manifest_clean_sizes.mpd")
													.get())
													.get()
									}
							).get()),
	};


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ListView demosList = (ListView) findViewById(R.id.demos_list);
		List<Demo> demos = Arrays.asList(DEMOS);
		final ArrayAdapter<Demo> demoAdapter = new ArrayAdapter<Demo>(this, R.layout.demo_list_item, demos) {
			@Override
			@NonNull
			public View getView(int position, View convertView, @NonNull ViewGroup parent) {
				View view = convertView == null ? getLayoutInflater().inflate(R.layout.demo_list_item, parent, false) : convertView;
				Demo item = getItem(position);
				if (item != null) {
					((TextView) view.findViewById(R.id.title)).setText(item.name);
					((TextView) view.findViewById(R.id.description)).setText(item.description);
				}
				return view;
			}
		};

		demosList.setAdapter(demoAdapter);
		demosList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
				Demo item = demoAdapter.getItem(position);
				if (item != null) {
					item.start(MainActivity.this);
				}
			}
		});
	}

	static class Demo {
		public final String name;
		private final String description;
		private final Class<? extends Activity> activityClass;
		private final Bundle bundle;

		Demo(String name, String description, Class<? extends Activity> activityClass, Bundle bundle) {
			this.name = name;
			this.description = description;
			this.activityClass = activityClass;
			this.bundle = bundle;
		}

		void start(Context context) {
			context.startActivity(new Intent(context, activityClass).putExtras(bundle));
		}
	}

	private static class BundleBuilder {
		private final Bundle bundle;

		BundleBuilder() {
			this.bundle = new Bundle();
		}

		BundleBuilder(boolean live, @NonNull String assetId) {
			this.bundle = new Bundle();

			// assetID is different from title in the real world
			final CustomerData customerData = createCustomerData(assetId);

			// (Optional) Custom Options
			CustomOptions customOptions = new CustomOptions();
			//customOptions.setBeaconDomain("beacon.example.domaina

			// Create AnalyticsMetadata and set it in the Bundle used to open the PlayerController
			AnalyticsMetaData analyticsMetaData = MuxPlugin.createMetadata(live, assetId, customerData, customOptions, null);
			put(SdkConsts.INTENT_ANALYTICS_DATA, analyticsMetaData);
		}

		BundleBuilder put(String key, String value) {
			bundle.putString(key, value);
			return this;
		}

		BundleBuilder put(String key, int value) {
			bundle.putInt(key, value);
			return this;
		}

		BundleBuilder put(String key, long value) {
			bundle.putLong(key, value);
			return this;
		}

		BundleBuilder put(String key, boolean value) {
			bundle.putBoolean(key, value);
			return this;
		}

		BundleBuilder put(String key, Parcelable value) {
			bundle.putParcelable(key, value);
			return this;
		}

		BundleBuilder put(String key, Parcelable[] value) {
			bundle.putParcelableArray(key, value);
			return this;
		}

		Bundle get() {
			return bundle;
		}
	}

	private static CustomerData createCustomerData(@NonNull final String videoTitle) {

		// Create MUX CustomerData, fill in metadata
		CustomerVideoData videoData = new CustomerVideoData();
		videoData.setVideoTitle(videoTitle);
		videoData.setVideoLanguageCode("en");
		//videoData.setVideoProducer(...);
		//videoData.setVideoEncodingVariant(...);

		// Create MUX PlayerData
		CustomerPlayerData playerData = new CustomerPlayerData();
		playerData.setViewerUserId("userId");
		//playerData.setExperimentName(...);

		// An Environment Key can be set here, and will override the key used to initialize
		// the MuxPlugin (if any)
		//playerData.setEnvironmentKey("MUX_ENVIRONMENT_KEY");

		CustomerViewData viewData = new CustomerViewData();
		viewData.setViewSessionId("viewSessionId");

		// (Optional) Set custom dimensions data
		CustomData customData = new CustomData();
		customData.setCustomData1("customDimensionValue1");

		CustomerData customerData = new CustomerData(playerData, videoData, viewData);
		customerData.setCustomData(customData);

		return customerData;
	}
}
