/*
 * ************************************************************************
 *
 * ADOBE SYSTEMS INCORPORATED
 * Copyright 2013 Adobe Systems Incorporated
 * All Rights Reserved.
 * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the 
 * terms of the Adobe license agreement accompanying it.  If you have received this file from a 
 * source other than Adobe, then your use, modification, or distribution of it requires the prior 
 * written permission of Adobe.
 *
 **************************************************************************
 */

package com.adobe.primetime.reference.ui.catalog;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.adobe.mediacore.MediaResource;
import com.adobe.mediacore.metadata.AdSignalingMode;
import com.adobe.mediacore.metadata.AdvertisingMetadata;
import com.adobe.mediacore.metadata.Metadata;
import com.adobe.primetime.reference.utils.StringUtils;
import com.adobe.primetime.reference.PrimetimeReference;
import com.adobe.primetime.reference.feeds.ContentRenditionInfo;
import com.adobe.primetime.reference.feeds.IFeedItemAdapter;
import com.adobe.primetime.reference.feeds.ContentRenditionInfo.ContentType;
import com.adobe.primetime.reference.utils.SerializableNameValuePair;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


/**
 * The VideoItem class is the Primetime reference implementation's representation of one video
 * content item. The VideoItem class is built using the FeedItemAdapter
 * interface as the input and it invokes the FeedItemAdapter's APIs to populate
 * its own data structure, which is then used by the PSDK
 * 
 * @author dshei
 * 
 */
public class VideoItem implements Serializable {
	private static final long serialVersionUID = 1L;
	private final String LOG_TAG = "[Player]::VideoItem";

    private final String NODE_NAME_PROTECTIONDATA = "protectionData";
    private final String NODE_NAME_PROTECTIONDATA_DRMTYPE = "drmType";
    private final String NODE_NAME_PROTECTIONDATA_URL = "licenseServerUrl";
    

	
	private final String id;
	private final String title;
	private final ContentType type;
	private final Stream stream;
	private final Thumbnail thumbnail;
	private final List<SerializableNameValuePair> properties = new ArrayList<SerializableNameValuePair>();

	private final String licenseServerUrl;
	private final String drmType;
	//private final ProtectionData protectionData;
	

	/**
	 * Class constructor. The VideoItem class is built using the FeedItemAdapter
	 * interface as the input and invokes its APIs to populate its data
	 * structure. Using the IFeedItemAdapter as an input parameter exemplifies
	 * how any input feed format can be adapted to the data structures used by
	 * the PSDK
	 * 
	 * @param feedItemAdapter
	 * @throws Exception
	 */
	public VideoItem(IFeedItemAdapter feedItemAdapter) throws Exception {
		try {
			id = feedItemAdapter.getId();
			title = feedItemAdapter.getTitle();
			type = feedItemAdapter.getContentType();

            stream = new Stream(feedItemAdapter.getResourceMetadata(),
                    feedItemAdapter.getAdvertisingMetadata(),
                    feedItemAdapter.getAdSignalingMode());

			List<ContentRenditionInfo> renditionInfos = feedItemAdapter.getContentRenditions();
			for (ContentRenditionInfo rendition : renditionInfos)
			{
				stream.addManifest(rendition.getUrl(), rendition.getContentFormat());
			}

			thumbnail = new Thumbnail(
					feedItemAdapter.getStreamThumbnailSmall(),
					feedItemAdapter.getStreamThumbnailLarge());

			if (feedItemAdapter.getProperties() != null) {
				properties.addAll(feedItemAdapter.getProperties());
			}
          
			drmType = feedItemAdapter.getDrmType();
			licenseServerUrl = feedItemAdapter.getLicenseServerUrl();

		
		} catch (Exception e) {
			PrimetimeReference.logger.e(LOG_TAG + "#VideoItem", e.getMessage());
			throw e;
		}
	}

	/**
	 * Returns id of video item
	 * 
	 * @return String - containing the id of video item
	 */
	public String getId() {
		return id;
	}

	/**
	 * Returns title of video item
	 * 
	 * @return String - containing the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Returns the type of video item
	 * 
	 * @return ContentType - see ContentType enum definition
	 */
	public ContentType getType() {
		return type;
	}

    /**
     * Returns the AdSignalingMode configured for this stream.
     * @return this stream's AdSignalingMode
     *
     * @see com.adobe.mediacore.metadata.AdSignalingMode
     */
    public AdSignalingMode getAdSignalingMode()
    {
        return stream.adSignalingMode;
    }

    /**
     * Returns the AdvertisingMetadata configured for this stream.
     * @return this stream's AdvertisingMetadata
     * or null if no advertising metadata is configured for this stream
     */
    public AdvertisingMetadata getAdvertisingMetadata()
    {
        return stream.advertisingMetadata;
    }

    /**
     * Returns the resource metadata configured for this stream. The resource metadata contains
     * non-ad related metadata such as VHL configurations or Entitlement configurations. This metadata
     * is automatically set to the MediaPlayerResource when toMediaResource is called.
     * @return Metadata object containing any non-ad metadata for this stream.
     * @see #toMediaResource()
     */
    public Metadata getResourceMetadata()
    {
        return stream.resourceMetadata;
    }

	/**
	 * Returns thumbnail class of video item
	 * 
	 * @return Thumbnail - class that contains the url to display the video item
	 *         thumbnail
	 */
	public Thumbnail getThumbnail() {
		return thumbnail;
	}

	//public ProtectionData getProtectionData() { return protectionData; }
		
	/**
	 * Returns the properties of the video item
	 * 
	 * @return List<SerializableNameValuePair> - list of categories and keywords
	 *         related to the video item that can enhance a user's experience
	 */
	public List<SerializableNameValuePair> getProperties() {
		return properties;
	}

	/**
	 * Converts the video item to a PSDK class MediaResource that the
	 * MediaPlayer plays
	 * 
	 * @return MediaResource
	 * @throws IllegalArgumentException
	 */
	public MediaResource toMediaResource() throws IllegalArgumentException {
		String url = null;
		MediaResource.Type itemType = null;
		List<Stream.Manifest> manifests = stream.manifests;
		if (manifests.size() > 0) {
			url = manifests.get(0).getUrl();
            
            
            String extension = StringUtils.getFileExtension(url);
            MediaResource.Type type = MediaResource.Type.UNKNOWN;
            for (MediaResource.Type t : MediaResource.Type.values())
            {
                if (t.getValue().equalsIgnoreCase(extension))
                {
                    type = t;
                    break;
                }
            }
            
            itemType = type;
            
//			String type = manifests.get(0).getType().toString()
//					.toUpperCase(Locale.ROOT);
//			itemType = MediaResource.Type.valueOf(type);
		}

		if (url != null && itemType != null) {
			return new MediaResource(url, itemType, stream.resourceMetadata);
		}

		return null;
	}

	/**
	 * Gets the url of manifest
	 * 
	 * @return String - url of manifest
	 */
	public String getUrl() {
		String url = null;
		List<Stream.Manifest> manifests = stream.manifests;
		if (manifests.size() > 0) {
			url = manifests.get(0).getUrl();
		}

		return url;
	}

	/**
	 * Gets the stream type of manifest
	 * 
	 * @return String - type of manifest
	 */
	public String getStreamType() {
		String type = null;
		List<Stream.Manifest> manifests = stream.manifests;
		if (manifests.size() > 0) {
			type = manifests.get(0).getType();
		}

		return type;
	}

	/**
	 * The Thumbnail class contains the url to display the video item thumbnail.
	 * The url is obtained by invoking the API of the corresponding
	 * IFeedItemAdapter instance.
	 * 
	 * @author dshei
	 * 
	 */
	public class Thumbnail implements Serializable {
		private static final long serialVersionUID = 1L;
		private final String smallThumbnailUrl;
		private final String largeThumbnailUrl;

		public Thumbnail(String smallThumbnailUrl, String largeThumbnailUrl) {
			this.smallThumbnailUrl = smallThumbnailUrl;
			this.largeThumbnailUrl = largeThumbnailUrl;
		}

		/**
		 * Getter method for small thumbnail url
		 * 
		 * @return String - containing the small thumbnail url
		 */
		public String getSmallThumbnailUrl() {
			return smallThumbnailUrl;
		}

		/**
		 * Getter method for large thumbnail url
		 * 
		 * @return String - containing the large thumbnail url
		 */
		public String getLargeThumbnailUrl() {
			return largeThumbnailUrl;
		}
	}

	public String getDrmType()
	{
		return drmType;
	}

	public String getLicenseServerUrl()
	{
		return licenseServerUrl;
	}


	/**
	 * The Stream class contains information to play the actual stream, and is
	 * populated by invoking the APIs of the corresponding IFeedItemAdapter
	 * instance. It is populated with information obtained from the list of
	 * ContentRenditionInfo objects and Metadata. It represents information
	 * obtained from the ContentRenditionInfo as a Manifest object and
	 * Metadata information as just an internal variable.
	 * 
	 * @author dshei
	 * 
	 */
	public class Stream implements Serializable {
		private static final long serialVersionUID = 1L;
		private final Metadata resourceMetadata;
        private final AdvertisingMetadata advertisingMetadata;
		private final List<Manifest> manifests;
        private final AdSignalingMode adSignalingMode;

		public Stream() {
			this.manifests = new Vector<Manifest>();
			this.resourceMetadata = new Metadata();
            this.advertisingMetadata = new AdvertisingMetadata();
            this.adSignalingMode = AdSignalingMode.DEFAULT;
		}

		public Stream(Metadata metadata, AdvertisingMetadata adMetadata, AdSignalingMode adMode) {
			this.manifests = new Vector<Manifest>();
			this.resourceMetadata = metadata;
            this.advertisingMetadata = adMetadata;
            this.adSignalingMode = adMode;
		}


		/**
		 * Adds manifest object to list of manifests
		 * 
		 * @param url
		 *            - manifest url
		 * @param type
		 *            - see ManifestType enum definition
		 */
		protected void addManifest(String url, String type) {
			Manifest manifest = new Manifest(url, type);
			manifests.add(manifest);
		}

		/**
		 * The Manifest represents a rendition of the video item content, which
		 * can be alternate content, camera angles, etc
		 * 
		 * @author dshei
		 * 
		 */
		public class Manifest implements Serializable {
			private static final long serialVersionUID = 1L;
			private final String type;
			private final String url;

			/**
			 * Class constructor.
			 * 
			 * @param url
			 *            - of video content
			 * @param type
			 *            - see ManifestType enum definition
			 */
			public Manifest(String url, String type) {
				this.url = url;
				this.type = type;
			}

			/**
			 * Returns the ManifestType
			 * 
			 * @return ManifestType - see MediaResource.Type
             * @See com.adobe.mediacore.MediaResource$Type
			 */
			public String getType() {
				return type;
			}

			/**
			 * Returns the manifest url
			 * 
			 * @return String - containing the manifest url
			 */
			public String getUrl() {
				return url;
			}
		}
	}
	
	
    


}
