package com.twc.isa.PackageModule;

import org.apache.log4j.Logger;
import org.omg.CORBA.ORB;
import org.omg.CORBA.StringHolder;

import com.ttv.acs.beans.serviceHandlers.LocalContentStoreHandler;
import com.ttv.acs.stub.adi.WorkOrderRequest;
import com.ttv.acs.util.PConstants;
import com.ttv.acs.util.WorkflowAdaptor;
import com.twc.isa.AssetModule.AssetData;
import com.twc.isa.AssetModule.AssetFactory;
import com.twc.isa.AssetModule.AssetFactoryHelper;
import com.twc.isa.AssetModule.AssetHelper;
import com.twc.isa.AssetModule.AssetWithRelations;
import com.twc.isa.AssetModule.PlayFailed;
import com.twc.isa.ContentModule.Content;
import com.twc.isa.MetadataModule.Metadata;
import com.twc.isa.MetadataModule.MetadataList;
import com.twc.isa.ProductModule.Product;
import com.twc.isa.ServerModule.AdministrativeState;
import com.twc.isa.ServerModule.CompletionCode;
import com.twc.isa.ServerModule.NoGuiProvisioned;
import com.twc.isa.ServerModule.OperationalState;
import com.twc.isa.ServerModule.ProvisioningFailed;
import com.twc.isa.ServerModule.ServantBase_impl;
import com.twc.isa.ServerModule.ServantFactory_;
import com.twc.isa.ServerModule.Unimplemented;
import com.twc.isa.ServerModule.UnspecifiedException;
import com.twc.isa.SessionModule.Session;
import com.twc.isa.StreamModule.Stream;

/**
 * 
 * @author <a href="mailto:cbrown@tandbergtv.com">Corey Brown</a>
 *
 */
public class Package_impl extends PackagePOA {

	private final Logger log = Logger.getLogger(Package_impl.class);

	private PackageFactory packageFactory = null;
	private ORB            orb            = null;
	private Product[]      products       = null;
	
	protected AdministrativeState administrativeState = null;
	protected OperationalState    operationalState    = null;
	
	public com.twc.isa.AssetModule.Asset base = null;
	public String url     = null;
	public String strName = null;
	
	//
	// Some methods that we need in order for this class to compile
	//
	
	public void 
	sendNotifications() {
		log.debug("sendNotifications called. Unimplemented.");
	}
	
	public void 
	updateTitleMetadata() {
		log.debug("updateTitleMetadata called. Unimplemented.");
	}
	
	public AssetWithRelations 
	getAssetDetails() { 
		log.debug("getAssetDetails called. Unimplemented.");
		return null;
	
	}
	
	public Metadata[] getMetadata() { 
		log.debug("getMetadata called. Unimplemented.");
		return null; 
	}
	
	public void 
	setAssetGroupID(String groupID, String groupType) {
		log.debug("setAssetGroupID called. Unimplemented.");
	}
	
	public AssetData 
	getAssetData() { 
		log.debug("getAssetData called. Unimplemented.");
		return null;
	}
	
	public int 
	getN2BBAssetVersion() {
		log.debug("getN2BBAssetVersion called. Unimplemented.");
		return 0;
	}
	
	public String 
	getAssetGroupID(String grpType) {
		log.debug("getAssetGroupID called. Unimplemented.");
		return null; 
	}
	
	public void 
	reconcileContents() {
		log.debug("reconcileContents called. Unimplemented.");
	}
	
	public void 
	removeAsset(com.twc.isa.AssetModule.Asset a) {
		log.debug("removeAsset called. Unimplemented.");
	}

	/**
	 * Constructor
	 *
	 */
	public Package_impl() {;}

	/**
	 * Constructor
	 * @param orb
	 * @param strName
	 */
	public Package_impl(ORB orb, String strName) {
		
		log.debug("Package_impl called. StrName: " + strName);

		// Get the refrence of the Asset factory
		
		String[] strFullPath = { "Factories", "AssetFactory" };
		org.omg.CORBA.Object factoryObj = ServantBase_impl.getFactoryObject(orb, strFullPath);
		AssetFactory Assetfactory = AssetFactoryHelper.narrow(factoryObj);
		
		try {
			this.base = AssetHelper.narrow(Assetfactory.createServant(strName));
		} catch (Exception ex) {
			log.error("Caught exception narrowing asset factory helpter.", ex);
		}
		
		this.orb = orb;
	}

	public PackageFactory 
	thePackageFactory() {
		log.debug("thePackageFactory called.");
		return packageFactory;
	}

	public void 
	thePackageFactory(PackageFactory value) {
		log.debug("thePackageFactory called.");
		packageFactory = value;
	}

	public com.twc.isa.ProductModule.Product[] 
	aProduct() {
		log.debug("aProduct called.");
		return products;
	}

	public void 
	aProduct(com.twc.isa.ProductModule.Product[] value) {
		log.debug("aProduct called.");
		this.products = value;
	}

	public AssetFactory 
	theAssetFactory() {
		log.debug("theAssetFactory called.");
		return base.theAssetFactory();
	}

	public void 
	theAssetFactory(AssetFactory value) {
		log.debug("theAssetFactory called.");
		base.theAssetFactory(value);
	}

	public MetadataList 
	theMetadataList() {
		log.debug("theMetadataList called.");
		return base.theMetadataList();
	}

	public void 
	theMetadataList(MetadataList value) {
		log.debug("theMetadataList called.");
		base.theMetadataList(value);
	}

	public com.twc.isa.ContentModule.Content[] 
	aContent() {
		log.debug("aContent called.");
		return base.aContent();
	}

	public void 
	aContent(com.twc.isa.ContentModule.Content[] value) {
		log.debug("aContent called.");
		base.aContent(value);
	}

	public com.twc.isa.AssetModule.Asset[] 
	aChildAsset() {
		log.debug("aChildAsset called.");
		return base.aChildAsset();
	}

	public void 
	aChildAsset(com.twc.isa.AssetModule.Asset[] value) {
		log.debug("aChildAsset called.");
		base.aChildAsset(value);
	}

	public com.twc.isa.AssetModule.Asset 
	theParentAsset() {
		log.debug("theParentAsset called.");
		return base.theParentAsset();
	}

	public void 
	theParentAsset(com.twc.isa.AssetModule.Asset value) {
		log.debug("theParentAsset called.");
		base.theParentAsset(value);
	}

	public com.twc.isa.ContentModule.Content 
	locateContent(int serviceGroup)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.SessionModule.InvalidServiceGroup,
			com.twc.isa.ServerModule.OutOfService,
			com.twc.isa.AssetModule.ContentNotFound {
		log.debug("locateContent called.");
		return base.locateContent(serviceGroup);
	}

	public void 
	getProvisioning (
		org.omg.CORBA.StringHolder name,
		com.twc.isa.ProductModule.ProductListHolder theProductListHolder,
		com.twc.isa.MetadataModule.MetadataListHolder theMetadataListHolder,
		com.twc.isa.ContentModule.ContentListHolder theContentListHolder,
		com.twc.isa.AssetModule.AssetListHolder theAssetListHolder,
		com.twc.isa.AssetModule.AssetHolder theAssetHolder,
		org.omg.CORBA.StringHolder theUrl,
		com.twc.isa.ServerModule.AdministrativeStateHolder theAdministrativeState,
		com.twc.isa.ServerModule.OperationalStateHolder theOperationalState)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.ServantNotProvisioned {
		
		log.debug("getProvisioning called.");

		theProductListHolder.value = products;
		theUrl.value = url;
		base.getAssetProvisioning (
			name,
			theMetadataListHolder,
			theContentListHolder,
			theAssetHolder,
			theAssetListHolder,
			theOperationalState,
			theAdministrativeState);
	}

	public void 
	addAsset(com.twc.isa.AssetModule.Asset a) {
		log.debug("addAsset called.");
	}

	public void 
	provisionAsset (
		com.twc.isa.ServerModule.AdministrativeState theAdministrativeState)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.InvalidStateChange,
			com.twc.isa.ServerModule.ProvisioningFailed {
		
		log.debug("provisionAsset called.");
		base.setAdminState(theAdministrativeState);
	}

	public void 
	provisioningGui(StringHolder strHolder)
		throws NoGuiProvisioned {
		
		log.debug("provisioningGui called.");
		
		String strName = getClass().getName();
		int    iIdx    = strName.lastIndexOf("_");
		String strTxtFileName = strName.substring(0, iIdx) + "ProvisioningURL.txt";
		strHolder.value = ServantFactory_.getProvisionGUI_URL_Name(strTxtFileName);
	}

	public void 
	statusGui(org.omg.CORBA.StringHolder strHolder)
		throws NoGuiProvisioned {
		
		log.debug("statusGui called.");
		
		String strName = getClass().getName();
		int iIdx = strName.lastIndexOf("_");
		String strTxtFileName = strName.substring(0, iIdx) + "StatusURL.txt";
		strHolder.value =
			ServantFactory_.getProvisionGUI_URL_Name(strTxtFileName);
	}

	public void 
	destroy()
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.DestroyFailed {
		
		log.debug("destroy called.");
		base.destroy();
	}

	public String 
	name() {
		
		log.debug("name called.");
		return base.name();
	}

	public com.twc.isa.ServerModule.AdministrativeState 
	getAdminState()
		throws com.twc.isa.ServerModule.UnspecifiedException {
		
		log.debug("getAdminState called.");
		return base.getAdminState();
	}

	public void 
	setAdminState(com.twc.isa.ServerModule.AdministrativeState st)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.InvalidStateChange {
		
		log.debug("setAdminState called.");
		base.setAdminState(st);
	}

	public void 
	getCreateTime(org.omg.CORBA.LongHolder longHolder)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.Unimplemented {
		
		log.debug("getCreateTime called.");
		base.getCreateTime(longHolder);
	}

	public void 
	getLastModifiedTime(org.omg.CORBA.LongHolder longHolder)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.Unimplemented {
		
		log.debug("getLastModifiedTime called.");
		base.getLastModifiedTime(longHolder);
	}

	public com.twc.isa.ServerModule.OperationalState 
	getOpState()
		throws com.twc.isa.ServerModule.UnspecifiedException {
		
		log.debug("getOpState called.");
		return base.getOpState();
	}

	public void 
	getAssetProvisioning (
		org.omg.CORBA.StringHolder name,
		com.twc.isa.MetadataModule.MetadataListHolder theMetadataList,
		com.twc.isa.ContentModule.ContentListHolder contentListHolder,
		com.twc.isa.AssetModule.AssetHolder theParentAsset,
		com.twc.isa.AssetModule.AssetListHolder aChildAssetList,
		com.twc.isa.ServerModule.OperationalStateHolder theOperationalState,
		com
			.twc
			.isa
			.ServerModule
			.AdministrativeStateHolder theAdministrativeState)
		throws
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.ServantNotProvisioned {
		
		log.debug("getAssetProvisioning called.");
		base.getAssetProvisioning(
			name,
			theMetadataList,
			contentListHolder,
			theParentAsset,
			aChildAssetList,
			theOperationalState,
			theAdministrativeState);
	}

	public void 
	logPurchase(String str, String str1)
		throws
			com.twc.isa.ServerModule.ServantNotFound,
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.Unimplemented,
			com.twc.isa.ServerModule.OutOfService {
		
		log.debug("logPurchase called.");
		throw new Unimplemented( "", "", CompletionCode.cc_No);
	}

	public Stream 
	play(Session session, int param)
		throws
			com.twc.isa.ServerModule.ServantNotFound,
			com.twc.isa.AssetModule.StreamFailed,
			com.twc.isa.AssetModule.PlayFailed,
			com.twc.isa.ServerModule.UnspecifiedException,
			com.twc.isa.ServerModule.OutOfService {
		
		log.debug("play called.");
		throw new PlayFailed( "", "", CompletionCode.cc_No);
	}

	public Content[] 
	returnContents()
		throws com.twc.isa.ServerModule.UnspecifiedException {
		log.debug("returnContents called.");
		return base.returnContents();
	}

	public void 
	theDirectoryUrl(String str) {
		log.debug("theDirectoryUrl called.");
		url = str;
	}

	public String 
	theDirectoryUrl() {
		log.debug("theDirectoryUrl called.");
		return url;
	}


	/**
	 * Provision the asset
	 * @throws UnspecifiedException 
	 */
	public void provision(AdministrativeState theAdministrativeState, String contentUrl)
		throws ProvisioningFailed, UnspecifiedException {
		
		log.debug("provision called.");
		WorkOrderRequest workOrderRequest = null;
		try {

			if (contentUrl == null || contentUrl.length() == 0) {
				String errString = "provision envoked with invalid content URL. Provisioning failed.";
				log.error(errString);
				throw new ProvisioningFailed(errString, CompletionCode.cc_No);
			}
			
			LocalContentStoreHandler contentStore = LocalContentStoreHandler.getInstance();
			workOrderRequest = contentStore.provisionPackage("package", contentUrl);

		} catch (Exception e) {
			workOrderRequest = new WorkOrderRequest(contentUrl, e);
			log.error("Caught exception during provisiong process for content: " + contentUrl, e);
			throw new com.twc.isa.ServerModule.ProvisioningFailed(
				e.getMessage(),
				CompletionCode.cc_No);
		}finally{
			WorkflowAdaptor wfAdapter = new WorkflowAdaptor();
			boolean result = wfAdapter.notifyWorkFlow(workOrderRequest);
			if(PConstants.INGEST_FAILURE.equals(workOrderRequest.getSuccess())){
				log.error("Provision process failed for content: " + contentUrl + ". Error: " + workOrderRequest.getMessage());
				throw new com.twc.isa.ServerModule.ProvisioningFailed(
						workOrderRequest.getMessage(),
						CompletionCode.cc_No);
			}
			if(!result){
				throw new com.twc.isa.ServerModule.UnspecifiedException("Failed to notify WorkFlow System after provision is completed", CompletionCode.cc_No);
			}
		}
	}
}
