package com.castlabs.sdk.conviva_demo;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

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.android.SdkConsts;
import com.castlabs.android.drm.Drm;
import com.castlabs.android.drm.DrmTodayConfiguration;
import com.castlabs.android.player.PlayerConfig;
import com.castlabs.sdk.conviva.ConvivaAnalyticsSession;
import com.castlabs.sdk.conviva.ConvivaPlugin;
import com.castlabs.sdk.ima.ImaAdRequest;
import com.castlabs.sdk.ima.ImaStreamRequest;

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

public class MainActivity extends AppCompatActivity {

	public static final String INTENT_PLAYLIST = "INTENT_PLAYLIST";
	private static final String TAG = "MainActivity";

	private Demo[] DEMOS = new Demo[]{
			new Demo("DASH DRM - VOD", "Plays encrypted DASH VOD stream",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("DASH DRM - VOD, OFFSET", "Starts with 30 sec offset",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD with offset")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_POSITION_TO_PLAY, 30000000L)
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("DASH DRM - VOD, PAUSED", "Starts in paused state, creates analytics upon user pressing play",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD with paused")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_START_PLAYING, false)
							.put(SdkConsts.INTENT_ANALYTICS_SESSION_TYPE, SdkConsts.ANALYTICS_SESSION_TYPE_PLAY)
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("Simple Playback (IMA Ads)", "Loads and plays single pre-roll, mid-roll and post-roll ads during content playback.",
				SimplePlaybackDemo.class,
				new BundleBuilder(false, "VOD with IMA (Clear)", true)
					.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("DASH DRM - VOD, ADS", "Loads and plays single pre-roll, mid-roll and post-roll ads during content playback",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD with IMA", true)
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.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())
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("DASH CLEAR - LIVE", "Plays clear DASH live stream",
					SimplePlaybackDemo.class,
					new BundleBuilder(true, "LIVE")
							.put(SdkConsts.INTENT_URL, "https://livesim.dashif.org/livesim/mup_30/testpic_2s/Manifest.mpd")
							.get()),

			new Demo("DASH DRM - VOD, MANIFEST NOT FOUND", "Content manifest not found error",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD with manifest not found")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/notfound")
							.put(SdkConsts.INTENT_CONTENT_TYPE, SdkConsts.CONTENT_TYPE_DASH)
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("DASH DRM - VOD, SEGMENT NOT FOUND", "Segments for the first 24secs only, then 404 error is returned",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "VOD with segment not found")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/QA/QA_BBB_single_4/Manifest.mpd")
							.put(SdkConsts.INTENT_CONTENT_TYPE, SdkConsts.CONTENT_TYPE_DASH)
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("DASH DRM - VOD - Releasable Player", "Plays encrypted DASH VOD stream",
					ReleasablePlayerPlaybackDemo.class,
					new BundleBuilder(false, "VOD")
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("Single Controller Playlist demo", "Creates a playlist with 3 items which uses the SingleControllerPlaylist.",
					SingleControllerPlaylistDemo.class,
					new BundleBuilder(false, "Single Controller Playlist demo")
							.put(INTENT_PLAYLIST,
									new PlayerConfig[]{
											new PlayerConfig.Builder("http://demo.cf.castlabs.com/media/TOS/DASH/DEMO.mpd")
													.drmConfiguration(new DrmTodayConfiguration.Builder(
															DrmTodayConfiguration.DRMTODAY_STAGING,
															"purchase",
															"sessionId",
															"six",
															"dasheverywhere_demo",
															Drm.Widevine
													).get())
													.analyticsMetaData(ConvivaPlugin.createMetadata(false, "TOS", C.CONVIVA_VIEWER_ID, null, null))
													.get(),
											new PlayerConfig.Builder("http://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(ConvivaPlugin.createMetadata(false, "BBB", C.CONVIVA_VIEWER_ID, null, null))
													.get(),
											new PlayerConfig.Builder("http://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(ConvivaPlugin.createMetadata(false, "TOS2", C.CONVIVA_VIEWER_ID, null, null))
													.get()
									})
							.get()),

		/*
			new Demo("Multi Controller Playlist demo", "Creates a playlist with 3 items which uses the MultiControllerPlaylist.",
					MultiControllerPlaylistDemo.class,
					new BundleBuilder(false, "Multi Controller Playlist demo")
							.put(MultiControllerPlaylistDemo.PLAY_BACKGROUND, false)
							.put(MultiControllerPlaylistDemo.BACK_PLAYERS, 1)
							.put(MultiControllerPlaylistDemo.FORWARD_PLAYERS, 1)
							.put(INTENT_PLAYLIST,
									new PlayerConfig[]{
											new PlayerConfig.Builder("http://demo.cf.castlabs.com/media/TOS/DASH/DEMO.mpd")
													.drmConfiguration(new DrmTodayConfiguration.Builder(
															DrmTodayConfiguration.DRMTODAY_STAGING,
															"purchase",
															"sessionId",
															"six",
															"dasheverywhere_demo",
															Drm.Widevine
													).get())
													.get(),
											new PlayerConfig.Builder("http://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())
													.get(),
											new PlayerConfig.Builder("http://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())
													.get()
									})
							.get()),

			new Demo("Multi Controller Playlist - Live", "Creates a playlist with 3 live items in order to simulate the live channel use case.",
					MultiControllerPlaylistDemo.class,
					new BundleBuilder(false, "Multi Controller Playlist demo")
							.put(MultiControllerPlaylistDemo.PLAY_BACKGROUND, true)
							.put(MultiControllerPlaylistDemo.BACK_PLAYERS, 1)
							.put(MultiControllerPlaylistDemo.FORWARD_PLAYERS, 1)
							.put(INTENT_PLAYLIST,
									new PlayerConfig[]{
											new PlayerConfig.Builder("http://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd")
													.get(),
											new PlayerConfig.Builder("http://livesim.dashif.org/livesim/start_1800/testpic_2s/Manifest.mpd")
													.get(),
											new PlayerConfig.Builder("http://livesim.dashif.org/livesim/start_900/testpic_2s/Manifest.mpd")
													.get()
									}
							)
							.get()),*/

			new Demo("Ad Start Failure", "This content is used to test ASF",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "Ad Start Failure", true)
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_ADVERTS_DATA, new ImaAdRequest("https://players.castlabs.com/ads/vast?id=6").toAdRequest())
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("Ad Playback Failure", "This content is used to test APF",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "Ad Playback Failure", true)
							.put(SdkConsts.INTENT_URL, "https://demo.cf.castlabs.com/media/tos_new/DEMO.mpd?v=2")
							.put(SdkConsts.INTENT_ADVERTS_DATA, new ImaAdRequest("https://players.castlabs.com/ads/vast?id=5").toAdRequest())
							.put(SdkConsts.INTENT_DRM_CONFIGURATION, new DrmTodayConfiguration.Builder(
									DrmTodayConfiguration.DRMTODAY_STAGING,
									"purchase",
									"p0",
									"six",
									null,
									Drm.Widevine
							).get())
							.get()),

			new Demo("Simple VOD Playback (IMA DAI DASH Ads)", "Loads and plays single pre-roll, mid-roll and post-roll ads during content playback.",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "IMA DAI DASH Ads", true)
							.put(SdkConsts.INTENT_CONTENT_TYPE, SdkConsts.CONTENT_TYPE_DASH)
							.put(SdkConsts.INTENT_ADVERTS_DATA, new ImaStreamRequest("2474148", "bbb-clear", null).toAdRequest())
							.get()),

			new Demo("Simple VOD Playback (IMA DAI HLS Ads)", "Loads and plays single pre-roll, mid-roll and post-roll ads during content playback.",
					SimplePlaybackDemo.class,
					new BundleBuilder(false, "IMA DAI HLS Ads", true)
							.put(SdkConsts.INTENT_CONTENT_TYPE, SdkConsts.CONTENT_TYPE_HLS)
							.put(SdkConsts.INTENT_ADVERTS_DATA, new ImaStreamRequest("19463", "googleio-highlights", null).toAdRequest())
							.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);
				}
			}
		});

		checkPermissions();
	}

	private void checkPermissions() {
		if (Build.VERSION.SDK_INT >= 23) {
			if (!(checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
				requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
			}
		}

		if (Build.VERSION.SDK_INT >= 29) {
			if ( !(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
				requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
			}
		}
	}

	private static final 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 final class BundleBuilder {
		private final Bundle bundle;

		BundleBuilder(boolean live, @NonNull String assetId) {
			this(live, assetId, false);
		}

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

			// Create extra tags
			Bundle extra = new Bundle();
			// Conviva predefined tags
			extra.putString(ConvivaAnalyticsSession.META_KEY_APPLICATION_NAME, C.CONVIVA_APP_NAME);
			extra.putString(ConvivaAnalyticsSession.META_KEY_DEFAULT_RESOURCE, C.CONVIVA_DEFAULT_RESOURCE);
			extra.putString("c3.app.version", C.CONVIVA_APP_VERSION);
			extra.putString("c3.cm.channel", C.CONVIVA_CHANNEL);
			extra.putString("c3.cm.brand", C.CONVIVA_BRAND);
			extra.putString("c3.cm.affiliate", C.CONVIVA_AFFILIATE);
			extra.putString("c3.cm.categoryType", C.CONVIVA_CATEGORY_TYPE);
			extra.putString("c3.cm.name", C.CONVIVA_NAME);
			extra.putString("c3.cm.id", C.CONVIVA_ID);
			extra.putString("c3.cm.seriesName", C.CONVIVA_SERIES_NAME);
			extra.putString("c3.cm.seasonNumber", C.CONVIVA_SEASON_NUMBER);
			extra.putString("c3.cm.showTitle", C.CONVIVA_SHOW_TITLE);
			extra.putString("c3.cm.episodeNumber", C.CONVIVA_EPISODE_NUMBER);
			extra.putString("c3.cm.primaryGenre", C.CONVIVA_PRIMARY_GENRE);
			extra.putString("c3.cm.genre", C.CONVIVA_GENRE);
			extra.putString("c3.cm.genreList", C.CONVIVA_GENRE_LIST);
			extra.putString("c3.cm.utmTrackingUrl", C.CONVIVA_UTM_TRACKING_URL);
			extra.putString("c3.cm.assetProviderName", C.CONVIVA_ASSET_PROVIDER_NAME);
			extra.putString("c3.cm.assetId", C.CONVIVA_ASSET_ID);

			// Required custom tag
			extra.putString("format", C.CONVIVA_FORMAT);

			// Optional custom tags
			Bundle customTags = new Bundle();
			customTags.putString("sampleCustomTag", "sampleCustomValue");

			// Required Ad tags
			Bundle adTags = new Bundle();
			if (includeAdTags) {
				adTags.putString(ConvivaAnalyticsSession.META_KEY_DEFAULT_RESOURCE, C.CONVIVA_DEFAULT_RESOURCE);
				adTags.putString("c3.app.version", C.CONVIVA_APP_VERSION);
				adTags.putString("c3.ad.unitName", C.CONVIVA_AD_UNIT_NAME);
				adTags.putString("c3.ad.sequence", C.CONVIVA_AD_SEQUENCE);
				adTags.putString("c3.ad.creativeName", C.CONVIVA_AD_CREATIVE_NAME);
				adTags.putString("c3.ad.breakId", C.CONVIVA_AD_BREAK_ID);
				adTags.putString("c3.ad.category", C.CONVIVA_AD_CATEGORY);
				adTags.putString("c3.ad.classification", C.CONVIVA_AD_CLASSIFICATION);
				adTags.putString("c3.ad.advertiser", C.CONVIVA_AD_ADVERTISER);
				adTags.putString("c3.ad.advertiserCategory", C.CONVIVA_AD_ADVERTISER_CATEGORY);
				adTags.putString("c3.ad.advertiserId", C.CONVIVA_AD_ADVERTISER_ID);
				adTags.putString("c3.ad.campaignName", C.CONVIVA_AD_CAMPAIGN_NAME);
				adTags.putString("c3.ad.dayPart", C.CONVIVA_AD_DAY_PART);
				adTags.putString("c3.ad.adManagerName", C.CONVIVA_AD_MANAGER_NAME);
				adTags.putString("c3.ad.adManagerVersion", C.CONVIVA_AD_MANAGER_VERSION);
				adTags.putString("c3.ad.sessionStartEvent", C.CONVIVA_AD_SESSION_START_EVENT);
				adTags.putString("c3.ad.id", C.CONVIVA_AD_ID);
				adTags.putString("c3.ad.system", C.CONVIVA_AD_SYSTEM);
				adTags.putString("c3.ad.mediaFileApiFramework", C.CONVIVA_AD_MEDIA_FILE_API_FRAMEWORK);
				adTags.putString("c3.ad.adStitcher", C.CONVIVA_AD_STITCHER);
				adTags.putString("c3.ad.firstAdSystem", C.CONVIVA_AD_FIRST_AD_SYSTEM);
				adTags.putString("c3.ad.firstAdId", C.CONVIVA_AD_FIRST_AD_ID);
				adTags.putString("c3.ad.firstCreativeId", C.CONVIVA_AD_FIRST_CREATIVE_ID);
				adTags.putString("c3.ad.creativeId", C.CONVIVA_AD_CREATIVE_ID);
			}

			put(SdkConsts.INTENT_ANALYTICS_DATA, ConvivaPlugin.createMetadata(live, assetId, C.CONVIVA_VIEWER_ID, extra, customTags, adTags));
		}

		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;
		}
	}
}
