<?xml version="1.0" encoding="UTF-8" ?>
<!--
  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.

-->
<library>

<class name="BaseURLLoadTest" extends="NetworkTest">

    <switch>
        <when property="$as3">
            <passthrough>
                import flash.events.*;
                import flash.net.*;
                import flash.utils.*;
            </passthrough>
        </when>
    </switch>

    <attribute name="testsCount" type="number" value="0" />
    <attribute name="testTypeParameter" type="string" value="null" />
    <attribute name="verbose" type="boolean" value="true" />

    <attribute name="startTime" type="number" value="0" />
    <attribute name="wholeTime" type="number" value="0" />
    <attribute name="maxTime" type="number" value="0" />
    <attribute name="minTime" type="number" value="999999" />
    <attribute name="finishedTestsCount" type="number" value="0" />
    <attribute name="successfulTestsCount" type="number" value="0" />

    <attribute name="hostUrl" type="string" value="" />
    <attribute name="loaderInited" type="boolean" value="false" />
    <attribute name="request" value="null" />
    <attribute name="loader" value="null" />

    <method name="initLoader">
        hostUrl = getBaseUrl() + "networktest.upload?testType=" + testTypeParameter;
        request = new URLRequest(hostUrl);

        loader = new URLLoader();
        loader.addEventListener(Event.COMPLETE, this.onComplete);
        loader.addEventListener(IOErrorEvent.IO_ERROR, this.onError);
        loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onError);

        loaderInited = true;
    </method>

    <method name="start">
        if (!loaderInited) {
            this.initLoader();
        }
        finishedTestsCount = 0;
        successfulTestsCount = 0;
        wholeTime = 0;
        maxTime = 0;
        minTime = 999999;

        this.log("start test... " + hostUrl);
        startTime = getTimer();
        loader.load(request);
    </method>

    <method name="forcedStop">
        loader.close();
        this.log("stopped");
    </method>

    <method name="onComplete" args="e">
        <![CDATA[
        var endTime = getTimer();
        var pingTime = endTime - startTime;
        wholeTime += pingTime;
        if (pingTime > maxTime) {
            maxTime = pingTime;
        }
        if (pingTime < minTime) {
            minTime = pingTime;
        }

        if (verbose) {
            this.log("load time = " + pingTime + " ms");
        }

        finishedTestsCount++;
        successfulTestsCount++;
        if (finishedTestsCount < testsCount && running) {
            startTime = getTimer();
            loader.load(request);
        } else {
            this.report();
        }
        ]]>
    </method>

    <method name="onError" args="e">
        <![CDATA[
        if (verbose) {
            this.log("Error - " + e);
        }

        finishedTestsCount++;
        if (finishedTestsCount < testsCount && running) {
            startTime = getTimer();
            loader.load(request);
        } else {
            this.report();
        }
        ]]>
    </method>

    <method name="report">
        var report = "report:";
        if (successfulTestsCount > 0) {
            report += "\n" + this.generateReport();
        } else {
            report += " connection error";
        }
        this.log(report);

        if (successfulTestsCount > 0) {
            this.setPassed();
        } else {
            this.setFailed();
        }
    </method>

    <method name="generateReport" />

</class>

</library>
