////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.core
{

import flash.display.Loader;
import flash.events.Event;
import flash.events.ErrorEvent;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.system.SecurityDomain;
import flash.utils.ByteArray;
//import flash.utils.getTimer;        // PERFORMANCE_INFO

import mx.core.RSLData;
import mx.events.RSLEvent;
import mx.utils.SHA256;
import mx.utils.LoaderUtil;

[ExcludeClass]

/**
 *  @private
 *  Cross-domain RSL Item Class.
 * 
 *  The rsls are typically located on a different host than the loader. 
 *  There are signed and unsigned Rsls, both have a digest to confirm the 
 *  correct rsl is loaded.
 *  Signed Rsls are loaded by setting the digest of the URLRequest.
 *  Unsigned Rsls are check using actionScript to calculate a sha-256 hash of 
 *  the loaded bytes and compare them to the expected digest.
 * 
 */
public class CrossDomainRSLItem extends RSLItem
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    private var rsls:Array = [];     // of type RSLInstanceData
//    private var rslUrls:Array;  // first url is the primary url in the url parameter, others are failovers
//    private var policyFileUrls:Array; // optional policy files, parallel array to rslUrls
//    private var digests:Array;      // option rsl digest, parallel array to rslUrls
//    private var isSigned:Array;     // each entry is a boolean value. "true" if the rsl in the parallel array is signed
//    private var hashTypes:Array;     //  type of hash used to create the digest
    private var urlIndex:int = 0;   // index into url being loaded in rslsUrls and other parallel arrays

    // this reference to the loader keeps the loader from being garbage 
    // collected before the complete event can be sent. 
    private var loadBytesLoader:Loader; 
    
//    private var startTime:int;      // PERFORMANCE_INFO
        
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
    *  Create a cross-domain RSL item to load.
    * 
    *  @param rsls Array of Objects. Each Object describes and RSL to load. 
    *  The first Object in the Array is the primary RSL and the others are
    *  failover RSLs.
    *  @param rootURL provides the url used to locate relative RSL urls. 
    *  @param moduleFactory The module factory that is loading the RSLs. The
    *  RSLs will be loaded into the application domain of the given module factory.
    *  If a module factory is not specified, then the RSLs will be loaded into the 
    *  application domain of where the CrossDomainRSLItem class was first loaded.
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */  
    public function CrossDomainRSLItem(rsls:Array,
                             rootURL:String = null,
                             moduleFactory:IFlexModuleFactory = null)
    {
        super(rsls[0].rslURL, rootURL, moduleFactory);

        this.rsls = rsls;
        
        // startTime = getTimer(); // PERFORMANCE_INFO
    }


    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    

    /**
     *  Get the RSLData for the current RSL. This could be the primary RSL or one
     *  of the failover RSLs.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function get currentRSLData():RSLData
    {
        return RSLData(rsls[urlIndex]);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden Methods
    //
    //--------------------------------------------------------------------------
    
    
   /**
    * 
    * Load an RSL. 
    * 
    * @param progressHandler       receives ProgressEvent.PROGRESS events, may be null
    * @param completeHandler       receives Event.COMPLETE events, may be null
    * @param ioErrorHandler        receives IOErrorEvent.IO_ERROR events, may be null
    * @param securityErrorHandler  receives SecurityErrorEvent.SECURITY_ERROR events, may be null
    * @param rslErrorHandler       receives RSLEvent.RSL_ERROR events, may be null
    * 
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    override public function load(progressHandler:Function,
                                  completeHandler:Function,
                                  ioErrorHandler:Function,
                                  securityErrorHandler:Function,
                                  rslErrorHandler:Function):void 
    {
        chainedProgressHandler = progressHandler;
        chainedCompleteHandler = completeHandler;
        chainedIOErrorHandler = ioErrorHandler;
        chainedSecurityErrorHandler = securityErrorHandler;
        chainedRSLErrorHandler = rslErrorHandler;


/*      
        // Debug loading of swf files

        trace("begin load of " + url);
                if (Security.sandboxType == Security.REMOTE)
        {
            trace(" in REMOTE sandbox");    
        }
        else if (Security.sandboxType == Security.LOCAL_TRUSTED)
        {
            trace(" in LOCAL_TRUSTED sandbox");                 
        }
        else if (Security.sandboxType == Security.LOCAL_WITH_FILE)
        {
            trace(" in LOCAL_WITH_FILE sandbox");                   
        }
        else if (Security.sandboxType == Security.LOCAL_WITH_NETWORK)
        {
            trace(" in LOCAL_WITH_NETWORK sandbox");                    
        }
*  
*  @langversion 3.0
*  @playerversion Flash 9
*  @playerversion AIR 1.1
*  @productversion Flex 3
*/

        var rslData:RSLData = currentRSLData;
        urlRequest = new URLRequest(LoaderUtil.createAbsoluteURL(rootURL, rslData.rslURL));
        
        var loader:URLLoader = new URLLoader();
        loader.dataFormat = URLLoaderDataFormat.BINARY;

        // We needs to listen to certain events.
            
        loader.addEventListener(
            ProgressEvent.PROGRESS, itemProgressHandler);
            
        loader.addEventListener(
            Event.COMPLETE, itemCompleteHandler);
            
        loader.addEventListener(
            IOErrorEvent.IO_ERROR, itemErrorHandler);
            
        loader.addEventListener(
            SecurityErrorEvent.SECURITY_ERROR, itemErrorHandler);

        if (rslData.policyFileURL != "")
        {
            Security.loadPolicyFile(rslData.policyFileURL);
        }
        
        if (rslData.isSigned)
        {
            // load a signed rsl by specifying the digest
            urlRequest.digest = rslData.digest;
        }
        
//        trace("start load of " + urlRequest.url + " at " + (getTimer() - startTime)); // PERFORMANCE_INFO
        
        loader.load(urlRequest);
    }
    
    

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  Complete the load of the cross-domain rsl by loading it into the current
     *  application domain. The load was started by loadCdRSL.
     * 
     *  @param - urlLoader from the complete event.
     * 
     *  @return - true if the load was completed successfully or unsuccessfully, 
     *            false if the load of a failover rsl was started
     */
    private function completeCdRslLoad(urlLoader:URLLoader):Boolean
    {
        // handle player bug #204244, complete event without data after an error
        if (urlLoader == null || urlLoader.data == null || ByteArray(urlLoader.data).bytesAvailable == 0)
        {
            return true;
        }
        
        // load the bytes into the current application domain.
        loadBytesLoader = new Loader();
        var context:LoaderContext = new LoaderContext();
        var rslData:RSLData = currentRSLData;

        if (rslData.moduleFactory)
        {
            context.applicationDomain = rslData.moduleFactory.info()["currentDomain"];            
        }
        else if (moduleFactory)
        {
            context.applicationDomain = moduleFactory.info()["currentDomain"];
        }
        else
        {
            context.applicationDomain = ApplicationDomain.currentDomain;
        }
        
        context.securityDomain = null;
        
        // Set the allowCodeImport flag so we can load the RSL without a security error.
        context.allowCodeImport = true;

        // verify the digest, if any, is correct
        if (rslData.digest != null && rslData.verifyDigest)
        {
            var verifiedDigest:Boolean = false;
            if (!rslData.isSigned)
            {
                // verify an unsigned rsl
                if (rslData.hashType == SHA256.TYPE_ID)
                {
                    // get the bytes from the rsl and calculate the hash
                    var rslDigest:String = null;
                    if (urlLoader.data != null)
                    {
                        rslDigest = SHA256.computeDigest(urlLoader.data);
                    }

                    if (rslDigest == rslData.digest)
                    {
                        verifiedDigest = true;
                    }
                }
            }
            else
            {
                // signed rsls are verified by the player
                verifiedDigest = true;
            }           
            
            if (!verifiedDigest)
            {
                // failover to the next rsl, if one exists
                // no failover to load, all the rsls have failed to load
                // report an error.
                 // B Feature: externalize error message
                var hasFailover:Boolean = this.hasFailover();
                var rslError:ErrorEvent = new ErrorEvent(RSLEvent.RSL_ERROR);
                rslError.text = "Flex Error #1001: Digest mismatch with RSL " +
                                urlRequest.url + 
                                ". Redeploy the matching RSL or relink your application with the matching library.";
                itemErrorHandler(rslError);
                
                return !hasFailover;
            }
        }

        // load the rsl into memory
        loadBytesLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBytesCompleteHandler);
        loadBytesLoader.loadBytes(urlLoader.data, context);
        return true;
    }


    /**
    *  Does the current url being processed have a failover?
    * 
    * @return true if a failover url exists, false otherwise.
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function hasFailover():Boolean
    {
        return (rsls.length > (urlIndex + 1));
    }
    
    
    /**
    *  Load the next url from the list of failover urls.
    *  
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function loadFailover():void
    {
        // try to load the failover from the same node again
        if (urlIndex < rsls.length)
        {
            trace("Failed to load RSL " + currentRSLData.rslURL);
            trace("Failing over to RSL " + RSLData(rsls[urlIndex+1]).rslURL);
            urlIndex++;        // move to failover url
            url = currentRSLData.rslURL;
            load(chainedProgressHandler,
                 chainedCompleteHandler,
                 chainedIOErrorHandler,
                 chainedSecurityErrorHandler,
                 chainedRSLErrorHandler);    
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden Event Handlers
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function itemCompleteHandler(event:Event):void
    {
//        trace("complete load of " + url + " at " + (getTimer() - startTime)); // PERFORMANCE_INFO

        // complete loading the cross-domain rsl by calling loadBytes.
        completeCdRslLoad(event.target as URLLoader);
    }
    
    /**
     *  @private
     */
    override public function itemErrorHandler(event:ErrorEvent):void
    {
//        trace("error loading " + url + " at " + (getTimer() - startTime)); // PERFORMANCE_INFO

        // if a failover exists, try to load it. Otherwise call super()
        // for default error handling.
        if (hasFailover())
        {
            trace(decodeURI(event.text));
            loadFailover();
        }
        else 
        {
            super.itemErrorHandler(event);
        }
    }
    
    
    /**
     * loader.loadBytes() has a complete event.
     * Done loading this rsl into memory. Call the completeHandler
     * to start loading the next rsl.
     * 
     *  @private
     */ 
    private function loadBytesCompleteHandler(event:Event):void
    {
        loadBytesLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadBytesCompleteHandler);
        loadBytesLoader = null;
        super.itemCompleteHandler(event);           
    }
    
}
}