/*
 *******************************************************************************
 * Copyright (C) 1996-2007, 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.*;
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)
    {
        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());
                }
            }
        }
    }
}
