/*
 *******************************************************************************
 * Copyright (C) 1996-2005, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 */

package com.ibm.icu.dev.test.serializable;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestFmwk.Target;
//import com.ibm.icu.dev.test.serializable.SerializableTest;

/**
 * @author emader
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class CompatibilityTest extends TestFmwk
{
    public class FolderTarget extends Target
    {
        private Target head = new Target(null);
        private Target tail = head;
        
        public FolderTarget(String name)
        {
            super(name);
        }
        
        public void add(String className, InputStream is)
        {
            HandlerTarget newTarget = new HandlerTarget(className, is);
            
            tail.setNext(newTarget);
            tail = newTarget;
        }
        
        protected boolean validate()
        {
            return true;
        }
        
        protected void execute() throws Exception
        {
            params.indentLevel += 1;
            
            for (Target target = head.getNext(); target != null; target = target.getNext())
            {
                target.run();
            }
            
            params.indentLevel -= 1;
        }
    }

    public class HandlerTarget extends Target
    {
        protected SerializableTest.Handler handler = null;
        protected InputStream inputStream = null;
        
        public HandlerTarget(String name, InputStream is)
        {
            super(name);
            inputStream = is;
        }
        
        protected boolean validate()
        {
            handler = SerializableTest.getHandler(name);
            
            return handler != null;
        }
        
        protected void execute() throws Exception
        {
            if (params.inDocMode()) {
                // nothing to execute
            } else if (!params.stack.included) {
                ++params.invalidCount;
            } else {
                params.testCount += 1;
    
                try {
                    ObjectInputStream in = new ObjectInputStream(inputStream);
                    Object inputObjects[] = (Object[]) in.readObject();
                    Object testObjects[] = handler.getTestObjects();
                    boolean passed = true;
                    
                    in.close();
                    inputStream.close();
                    
                    // TODO: add equality test...
                    // The commented out code below does that,
                    // but some test objects don't define an equals() method,
                    // and the default method is the same as the "==" operator...
                    for (int i = 0; i < testObjects.length; i += 1) {
    //                    if (! inputObjects[i].equals(testObjects[i])) {
    //                        errln("Input object " + i + " failed equality test.");
    //                    }
                        
                        if (! handler.hasSameBehavior(inputObjects[i], testObjects[i])) {
                            warnln("Input object " + i + " failed behavior test.");
                        }
                    }
                }catch (MissingResourceException e){
                    warnln("Could not load the data. "+e.getMessage());
                } catch (Exception e) {
                    errln("Exception: " + e.toString());
                }
            }
        }
    }

    private Target getFileTargets(URL fileURL)
    {
        File topDir = new File(fileURL.getPath());
        File dataDirs[] = topDir.listFiles();
        FolderTarget target = null;
        
        for (int d = 0; d < dataDirs.length; d += 1) {
            File dataDir = dataDirs[d];
            
            if (dataDir.isDirectory()) {
                FolderTarget newTarget = new FolderTarget(dataDir.getName());
                File files[] = dataDir.listFiles();
                
                
                newTarget.setNext(target);
                target = newTarget;
                
                for (int i = 0; i < files.length; i += 1) {
                    File file = files[i];
                    String filename = file.getName();
                    int ix = filename.indexOf(".dat");
                    
                    if (ix > 0) {
                        String className = filename.substring(0, ix);
                        InputStream is;
                        
                        try {
                            is = new FileInputStream(file);
                            target.add(className, is);
                        } catch (FileNotFoundException e) {
                            errln("Exception: " + e.toString());
                        }
                        
                    }
                }
            }
        }
            
        return target;
    }
    
    private Target getJarTargets(URL jarURL)
    {
        String prefix = jarURL.getPath();
        String currentDir = null;
        int ix = prefix.indexOf("!/");
        JarFile jarFile;
        FolderTarget target = null;
        
        if (ix >= 0) {
            prefix = prefix.substring(ix + 2);
        }
        
        try {
            JarURLConnection conn = (JarURLConnection) jarURL.openConnection();
            
            jarFile = conn.getJarFile();

            Enumeration entries = jarFile.entries();
            
            while (entries.hasMoreElements()) {
                JarEntry entry = (JarEntry)entries.nextElement();
                String name = entry.getName();
                
                if (name.startsWith(prefix)) {
                    name = name.substring(prefix.length());
                    
                    if (! entry.isDirectory()) {
                        int dx = name.lastIndexOf("/");
                        String dirName  = name.substring(1, dx);
                        String filename = name.substring(dx + 1);
                        
                        if (! dirName.equals(currentDir)) {
                            currentDir = dirName;
                            
                            FolderTarget newTarget = new FolderTarget(currentDir);
                            
                            newTarget.setNext(target);
                            target = newTarget;
                        }
                        
                        int xx = filename.indexOf(".dat");
                        
                        if (xx > 0) {
                            String className = filename.substring(0, xx);

                            target.add(className, jarFile.getInputStream(entry));
                        }
                    }
                }
            }
        } catch (Exception e) {
            errln("jar error: " + e.getMessage());
        }
        
        return target;
    }
    
    protected Target getTargets(String targetName)
    {
        URL dataURL = getClass().getResource("data");
        String protocol = dataURL.getProtocol();
        
        if (protocol.equals("jar")) {
            return getJarTargets(dataURL);
        } else if (protocol.equals("file")) {
            return getFileTargets(dataURL);
        } else {
            errln("Don't know how to test " + dataURL.getPath());
            return null;
        }
    }

    public static void main(String[] args)
    {
        CompatibilityTest test = new CompatibilityTest();
        
        test.run(args);
    }
}
