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

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

import com.ibm.icu.impl.URLHandler;
import com.ibm.icu.dev.test.serializable.SerializableTest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.Class;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * This class examines all the classes in a Jar file or a directory
 * and lists all those classes that implement <code>Serializable</code>. It also checks
 * to make sure that those classes have the <code>serialVersionUID</code>
 * field define.
 * 
 */
public class SerializableChecker implements URLHandler.URLVisitor
{
    private static Class serializable;
    //private static Class throwable;
    
    private String path = null;
    
    private boolean write;
    
    public SerializableChecker(String path)
    {
        this.path = path;
        
        if (path != null) {
            File dir = new File(path);
            
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
    }
    
    static {
        try {    
            serializable = Class.forName("java.io.Serializable");
            //throwable    = Class.forName("java.lang.Throwable");
        } catch (Exception e) {
            // we're in deep trouble...
            System.out.println("Woops! Can't get class info for Serializable and Throwable.");
        }
    }
    
    private void writeFile(String className, byte bytes[])
    {
        File file = new File(path + File.separator + className + ".dat");
        FileOutputStream stream;
        
        try {
            stream = new FileOutputStream(file);
            
            stream.write(bytes);
            stream.close();
        } catch (Exception e) {
            System.out.print(" - can't write file!");
        }
    }
    
    public void visit(String str)
    {
        int ix = str.lastIndexOf(".class");
        
        if (ix >= 0) {
            String className = "com.ibm.icu" + str.substring(0, ix).replace('/', '.');
            
            // Skip things in com.ibm.icu.dev; they're not relevant.
            if (className.startsWith("com.ibm.icu.dev.")) {
                return;
            }
            
            try {
                Class c = Class.forName(className);
                int   m = c.getModifiers();
                
                if (serializable.isAssignableFrom(c) /*&&
                    (! throwable.isAssignableFrom(c) || c.getDeclaredFields().length > 0)*/) {
                    Field uid;
                    
                    System.out.print(className + " (" + Modifier.toString(m) + ") - ");
                    
                    try {
                        uid = c.getDeclaredField("serialVersionUID");
                    } catch (Exception e) {
                        System.out.print("no serialVersionUID - ");
                    }
                    
                    if (Modifier.isPublic(m)) {
                        SerializableTest.Handler handler = SerializableTest.getHandler(className);
                        
                        if (handler != null) {
                            Object objectsOut[] = handler.getTestObjects();
                            Object objectsIn[];
                            boolean passed = true;
                            
                            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                            ObjectOutputStream out = new ObjectOutputStream(byteOut);
                            
                            try {
                                out.writeObject(objectsOut);
                                out.close();
                                byteOut.close();
                            } catch (IOException e) {
                                System.out.println("Eror writing test objects:" + e.toString());
                                return;
                            }
                            
                            if (path != null) {
                                writeFile(className, byteOut.toByteArray());
                            }
                            
                            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
                            ObjectInputStream in = new ObjectInputStream(byteIn);
                            
                            try {
                                objectsIn = (Object[]) in.readObject();
                                in.close();
                                byteIn.close();
                            } catch (Exception e) {
                                System.out.println("Error reading test objects:" + e.toString());
                                return;
                            }

                            for(int i = 0; i < objectsIn.length; i += 1) {
                                if (! handler.hasSameBehavior(objectsIn[i], objectsOut[i])) {
                                    passed = false;
                                    System.out.println("Object " + i + " failed behavior test.");
                                }
                            }
                            
                            if (passed) {
                                System.out.print("test passed.");
                            }
                        } else {
                            // it's OK to not have tests for abstract classes...
                            if (! Modifier.isAbstract(m)) {
                                System.out.print("no test.");
                            }
                        }
                    }
                    
                    System.out.println();
                }
           } catch (Exception e) {
                System.out.println("Error processing " + className + ": " + e.toString());
            }
        }
    }

    public static void main(String[] args) throws java.net.MalformedURLException
    {
        List argList = Arrays.asList(args);
        String path = null;
        
        for (Iterator it = argList.iterator(); it.hasNext(); /*anything?*/) {
            String arg = (String) it.next();
            
            if (arg.equals("-w")) {
                if (it.hasNext()) {
                    path = (String) it.next();
                } else {
                    System.out.println("Missing directory name on -w command.");
                }
            } else {
                
    
                try {
                    //URL jarURL  = new URL("jar:file:/dev/eclipse/workspace/icu4j/icu4j.jar!/com/ibm/icu");
                    //URL fileURL = new URL("file:/dev/eclipse/workspace/icu4j/classes/com/ibm/icu");
                    URL url = new URL(arg);
                    URLHandler handler  = URLHandler.get(url);
                    SerializableChecker checker = new SerializableChecker(path);
                    
                    System.out.println("Checking classes from " + arg + ":");
                    handler.guide(checker, true, false);
                } catch (Exception e) {
                    System.out.println("Error processing URL \"" + arg + "\" - " + e.getMessage());
                }
            }
        }
    }
}
