package com.viaccessorca.voplayerdemo;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

import com.viaccessorca.voplayerdemo.mediamgt.StreamingMediaItem;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import static com.viaccessorca.voplayerdemo.Constants.DRM_AGENT_TYPE;
import static com.viaccessorca.voplayerdemo.Constants.DRM_CONTENT_IDENTIFIER;
import static com.viaccessorca.voplayerdemo.Constants.DRM_LICENSE_COOKIE_SKEY;
import static com.viaccessorca.voplayerdemo.Constants.DRM_LICENSE_CUSTOM_DATA_SKEY;
import static com.viaccessorca.voplayerdemo.Constants.DRM_LICENSE_URL_PARAMETERS_SKEY;
import static com.viaccessorca.voplayerdemo.Constants.DRM_LICENSE_URL_SKEY;
import static com.viaccessorca.voplayerdemo.Constants.DRM_LICENSE_USE_VOSECURITYGATEWAY;
import static com.viaccessorca.voplayerdemo.Constants.DRM_PERSONALIZATION_APPVERSION;
import static com.viaccessorca.voplayerdemo.Constants.DRM_PERSONALIZATION_CUSTOM_DATA;
import static com.viaccessorca.voplayerdemo.Constants.DRM_PERSONALIZATION_URL;
import static com.viaccessorca.voplayerdemo.Constants.FLAT_360_PLAYBACK_SUPPORT;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_ASSET;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_CHANNEL;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_END;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SERVER;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SERVICE_TYPE;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SPRITE_COLUMS;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SPRITE_INTERVAL;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SPRITE_LINES;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_SPRITE_RESOLUTION;
import static com.viaccessorca.voplayerdemo.Constants.SCRUBBING_OPTION_START;
import static com.viaccessorca.voplayerdemo.Constants.VAST_URL_INTENT_SKEY;

public class AppConfig {

    private final String TAG = "AppConfig";

    private static final String VOPLAYER_TAG = "voplayer";

    private static final String EMBEDDED_STREAMS_TAG = "embedded_streams";
    private static final String STREAM_TAG = "stream";

    private static final String NAME_TAG = "name";
    private static final String URI_KEY = "uri";
    private static final String VMX_BOOTADDRESS = "BootAddress";
    private static final String VMX_COMPANYNAME = "CompanyName";
    private static final String SECONDARY_CONTENT_URI = "SecondaryContentUri";

    private static AppConfig instance = null;
    private List<StreamingMediaItem> embeddedStreams;
    private boolean validConfig = true;

    protected AppConfig() {
        embeddedStreams = new ArrayList<StreamingMediaItem>();
    }

    private void readAppConfig(Context context) {

        InputStream configInputStream = null;
        try {
            AssetManager assets = context.getResources().getAssets();
            configInputStream = assets.open("config.xml", AssetManager.ACCESS_BUFFER);
        }
        catch(IOException ioee) {
            Log.w(TAG, "Warning: no configuration file in assets");
            configInputStream = null;
        }

        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(configInputStream);
            doc.getDocumentElement().normalize();

            Element rootElement = (Element) doc.getElementsByTagName(VOPLAYER_TAG).item(0);
            readEmbeddedStreams(rootElement, context);

        } catch (ParserConfigurationException e) {
            validConfig = false;
            e.printStackTrace();
        } catch (SAXException e) {
            validConfig = false;
            e.printStackTrace();
        } catch (IOException e) {
            validConfig = false;
            e.printStackTrace();
        }
    }

    private void readEmbeddedStreams(Element root, Context context) {

        Element embeddedStreamsSection = (Element) root.getElementsByTagName(EMBEDDED_STREAMS_TAG).item(0);

        if(null == embeddedStreamsSection) {
            Log.i(TAG, "no embedded streams section found");
            return;
        }

        NodeList embeddedStreamsNodes = embeddedStreamsSection.getChildNodes();

        if(null == embeddedStreams) {
            Log.i(TAG, "no embedded streams found");
            return;
        }

        for (int n = 0; n < embeddedStreamsNodes.getLength(); n++) {

            String storedUri = null;
            String storedName = null;
            String storedVmxBootAddress = null;
            String storedVmxCompanyName = null;
            String storedVastUrl = null;
            String storedSecondaryContentUri = null;
            String storedDrmAgentType = null;
            String storedDrmPersonalizationURL = null;
            String storedDrmPersonalizationAppVersion = null;
            String storedDrmPersonalizationCustomData = null;
            String storedDrmLicenseAcquisitionURL = null;
            String storedDrmLicenseAcquisitionURLParameters = null;
            String storedDrmLicenseAcquisitionCustomData = null;
            String storedDrmLicenseAcquisitionCookie = null;
            boolean storedDrmUseVOSecurityGateway = false;
            String storedDrmContentIdentifier = null;
            boolean stored360Content = false;
            String storedScrubbingOptionServer = null;
            String storedScrubbingOptionChannel = null;
            String storedScrubbingOptionAsset = null;
            String storedScrubbingOptionServiceType = null;
            String storedScrubbingOptionStart = null;
            String storedScrubbingOptionEnd = null;
            String storedScrubbingOptionSpriteResolution = null;
            String storedScrubbingOptionSpriteColums = null;
            String storedScrubbingOptionSpriteLines = null;
            String storedScrubbingOptionSpriteInterval = null;

            Node node = embeddedStreamsNodes.item(n);

            if (node.getNodeName().equals(STREAM_TAG)) {
                Element streamNode = (Element) node;

                storedName = streamNode.getAttribute(NAME_TAG);

                Log.i(TAG, "readEmbeddedStreams 1");

                NodeList streamParamsNode = streamNode.getChildNodes();
                for (int p = 0; p < streamParamsNode.getLength(); p++) {

                    Node param = streamParamsNode.item(p);
                    String nodeName = param.getNodeName();

                    Log.i(TAG, "readEmbeddedStreams nodeName = " + nodeName);

                    if (nodeName.equals(URI_KEY)) {
                        storedUri = param.getTextContent();
                    } else if (nodeName.equals(VMX_BOOTADDRESS)) {
                        storedVmxBootAddress = param.getTextContent();
                    } else if (nodeName.equals(VMX_COMPANYNAME)) {
                        storedVmxCompanyName = param.getTextContent();
                    } else if (nodeName.equals(SECONDARY_CONTENT_URI)) {
                        storedSecondaryContentUri = param.getTextContent();
                    } else if (nodeName.equals(DRM_AGENT_TYPE)){
                        storedDrmAgentType = param.getTextContent();
                    } else if (nodeName.equals(DRM_PERSONALIZATION_URL)) {
                        storedDrmPersonalizationURL = param.getTextContent();
                    } else if (nodeName.equals(DRM_PERSONALIZATION_APPVERSION)) {
                        storedDrmPersonalizationAppVersion = param.getTextContent();
                    } else if (nodeName.equals(DRM_PERSONALIZATION_CUSTOM_DATA)) {
                        storedDrmPersonalizationCustomData = param.getTextContent();
                    } else if (nodeName.equals(DRM_LICENSE_URL_SKEY)) {
                        storedDrmLicenseAcquisitionURL = param.getTextContent();
                    } else if (nodeName.equals(DRM_LICENSE_URL_PARAMETERS_SKEY)) {
                        storedDrmLicenseAcquisitionURLParameters = param.getTextContent();
                    } else if (nodeName.equals(DRM_LICENSE_CUSTOM_DATA_SKEY)) {
                        storedDrmLicenseAcquisitionCustomData = param.getTextContent();
                    } else if (nodeName.equals(DRM_LICENSE_COOKIE_SKEY)) {
                        storedDrmLicenseAcquisitionCookie = param.getTextContent();
                    } else if (nodeName.equals(FLAT_360_PLAYBACK_SUPPORT)) {
                        stored360Content = true;
                    } else if (nodeName.equals(VAST_URL_INTENT_SKEY)) {
                        storedVastUrl = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SERVER)) {
                        storedScrubbingOptionServer = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_CHANNEL)) {
                        storedScrubbingOptionChannel = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_ASSET)) {
                        storedScrubbingOptionAsset = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SERVICE_TYPE)) {
                        storedScrubbingOptionServiceType = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_START)) {
                        storedScrubbingOptionStart = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_END)) {
                        storedScrubbingOptionEnd = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SPRITE_RESOLUTION)) {
                        storedScrubbingOptionSpriteResolution = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SPRITE_COLUMS)) {
                        storedScrubbingOptionSpriteColums = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SPRITE_LINES)) {
                        storedScrubbingOptionSpriteLines = param.getTextContent();
                    } else if (nodeName.equals(SCRUBBING_OPTION_SPRITE_INTERVAL)) {
                        storedScrubbingOptionSpriteInterval = param.getTextContent();
                    } else if (nodeName.equals(DRM_LICENSE_USE_VOSECURITYGATEWAY)) {
                        storedDrmUseVOSecurityGateway = (param.getTextContent().equals("true") ? true : false);
                    } else if (nodeName.equals(DRM_CONTENT_IDENTIFIER)) {
                        storedDrmContentIdentifier = param.getTextContent();
                    } else {
                        Log.i(TAG, "readEmbeddedStreams - stream parameter not supported: " + param.getLocalName());
                    }
                }
                if (null != storedName && null != storedUri) {
                    StreamingMediaItem streamingItem = new StreamingMediaItem(Utils.getMD5Hash(storedName), storedUri, storedName, true);
                    streamingItem.setStoredName(storedName);
                    streamingItem.setCompanyName(storedVmxCompanyName);
                    streamingItem.setBootAddress(storedVmxBootAddress);
                    streamingItem.setSecondaryContentUri(storedSecondaryContentUri);
                    streamingItem.setDrmAgentType(storedDrmAgentType);
                    streamingItem.setDrmPersonalizationUrl(storedDrmPersonalizationURL);
                    streamingItem.setDrmPersonalizationAppVersion(storedDrmPersonalizationAppVersion);
                    streamingItem.setDrmPersonalizationCustomData(storedDrmPersonalizationCustomData);
                    streamingItem.setDRMLicenseAcquisitionUrl(storedDrmLicenseAcquisitionURL);
                    streamingItem.setDRMLicenseAcquisitionUrlParameters(storedDrmLicenseAcquisitionURLParameters);
                    streamingItem.setDRMLicenseAcquisitionCustomData(storedDrmLicenseAcquisitionCustomData);
                    streamingItem.setDRMLicenseAcquisitionCookie(storedDrmLicenseAcquisitionCookie);
                    streamingItem.set360Content(stored360Content);
                    streamingItem.setScrubbingOptionServer(storedScrubbingOptionServer);
                    streamingItem.setScrubbingOptionChannel(storedScrubbingOptionChannel);
                    streamingItem.setScrubbingOptionAsset(storedScrubbingOptionAsset);
                    streamingItem.setScrubbingOptionServiceType(storedScrubbingOptionServiceType);
                    streamingItem.setScrubbingOptionStart(storedScrubbingOptionStart);
                    streamingItem.setScrubbingOptionEnd(storedScrubbingOptionEnd);
                    streamingItem.setScrubbingOptionSpriteResolution(storedScrubbingOptionSpriteResolution);
                    streamingItem.setScrubbingOptionSpriteColums(storedScrubbingOptionSpriteColums);
                    streamingItem.setScrubbingOptionSpriteLines(storedScrubbingOptionSpriteLines);
                    streamingItem.setScrubbingOptionSpriteInterval(storedScrubbingOptionSpriteInterval);
                    streamingItem.setDrmUseVOSecurityGateway(storedDrmUseVOSecurityGateway);
                    streamingItem.setDrmContentIdentifier(storedDrmContentIdentifier);
                    //streamingItem.setVastUrl(storedVastUrl);
                    this.embeddedStreams.add(streamingItem);
                }
            }
        }
    }

    public static AppConfig getInstance(Context context) {
        if(null == instance) {
            instance = new AppConfig();
            instance.readAppConfig(context);
        }
        return instance;
    }

    public List<StreamingMediaItem> getEmbeddedStreams() {
        return embeddedStreams;
    }

    public boolean isConfigValid() {
        return validConfig;
    }
}
