/*
 * 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 flex.messaging.io.amf.validators;

import flex.messaging.config.ConfigMap;
import flex.messaging.io.MessageDeserializer;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.*;
import flex.messaging.validators.DeserializationValidator;
import macromedia.util.UnitTrace;
import org.junit.Assert;
import org.junit.Test;

import java.io.*;
import java.net.URI;
import java.net.URL;

public class AmfDeserializationValidatorTest {
    @Test
    public void testDeserializationValidator() {
        deserializateRequest(null);

        long duration1 = 0, duration2 = 0;
        DeserializationValidator validator = new TestDeserializationValidator();
        int n = 100; // Number of times to run the tests, use an even number.

        for (int i = 0; i < n / 2; i++) {
            long start1 = System.currentTimeMillis();
            deserializateRequest(null);
            duration1 += (System.currentTimeMillis() - start1);

            long start2 = System.currentTimeMillis();
            deserializateRequest(validator);
            duration2 += (System.currentTimeMillis() - start2);
        }

        for (int i = 0; i < n / 2; i++) {
            long start2 = System.currentTimeMillis();
            deserializateRequest(validator);
            duration2 += (System.currentTimeMillis() - start2);

            long start1 = System.currentTimeMillis();
            deserializateRequest(null);
            duration1 += (System.currentTimeMillis() - start1);
        }

        if (UnitTrace.debug) // Print trace output.
        {
            System.out.println("AMF Deserialization Time w/o validator: " + duration1 + "ms");
            System.out.println("AMF Deserialization Time w validator: " + duration2 + "ms");
        }
    }

    private void deserializateRequest(DeserializationValidator validator) {
        try {
            // Find sample AMF data, or read the default file.
            String sample = System.getProperty("AMF_SAMPLE_FILE");
            if (sample == null || sample.length() < 1)
                sample = "amf_request.xml";

            URL resource = ClassLoader.getSystemResource(sample);
            URI uri = new URI(resource.toString());
            File testData = new File(uri.getPath());
            String testDataLocation = testData.getCanonicalPath();

            // Generate sample AMF request from the data file.
            PipedOutputStream pout = new PipedOutputStream();
            DataOutputStream dout = new DataOutputStream(pout);

            DataInputStream din = new DataInputStream(new PipedInputStream(pout));

            AmfTrace trace = new AmfTrace();
            trace.startResponse("Serializing AMF/HTTP response");

            MessageGenerator gen = new MessageGenerator();
            gen.setDebugTrace(trace);
            gen.setOutputStream(dout);
            gen.parse(testDataLocation);
            trace.endMessage();
            trace.newLine();

            // Create a deserializer for sample AMF request.
            ActionContext context = new ActionContext();
            ActionMessage message = new ActionMessage();
            context.setRequestMessage(message);

            SerializationContext dsContext = SerializationContext.getSerializationContext();
            if (validator != null)
                dsContext.setDeserializationValidator(validator);
            MessageDeserializer deserializer = new AmfMessageDeserializer();
            deserializer.initialize(dsContext, din, trace);
            deserializer.readMessage(message, context);
            trace.endMessage();
            trace.newLine();

            //if (UnitTrace.debug) // Print trace output.
            //    System.out.print(trace.toString());
        } catch (Exception e) {
            e.printStackTrace();
            Assert.fail();
        }
    }

    // A simple deserialization validator that simply returns true for all creation
    // and assignments validations.
    class TestDeserializationValidator implements DeserializationValidator {
        public boolean validateAssignment(Object instance, int index, Object value) {
            //System.out.println("validateAssign: [" + (instance == null? "null" : instance.getClass().getName()) + "," + index + "," + value + "]");
            return true;
        }

        public boolean validateAssignment(Object instance, String propertyName, Object value) {
            //System.out.println("validateAssign: [" + (instance == null? "null" : instance.getClass().getName()) + "," + propertyName + "," + value + "]");
            return true;
        }

        public boolean validateCreation(Class<?> c) {
            //System.out.println("validateCreate: " + (c == null? "null" : c.getName()));
            return true;
        }

        public void initialize(String id, ConfigMap configMap) {
            // No-op
        }
    }
}
