package com.db4o.lib;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.jgen.JClass;
import java.lang.reflect.*;

public class Logger
{
	public static boolean silent = false;

	public static void log(ObjectContainer a_container, Object a_object){
		if(a_object == null){
			log("[NULL]");
		}else{
			log("OBJECT of class '" + a_object.getClass().getName() + "'");
			log(a_container, a_object, 0);
		}
	}

	static void log(ObjectContainer a_container, Object a_object, int a_depth){
		Class[] classes = JClass.getClassHierarchy(a_object);

		String spaces = "";
		for(int i = classes.length - 1; i >= 0; i--){
			spaces = spaces + " ";

			String className = spaces + Str._splitRight(classes[i].getName(),".");

			Field[] fields = classes[i].getDeclaredFields();
			for (int j = 0; j < fields.length; j++){

				String fieldName = className + "." + fields[j].getName();

				try{
					Object object = fields[j].get(a_object);

					if(fields[j].getType().isArray()){
						Class arrClass = fields[j].getType().getComponentType();
						int len = Array.getLength(object);
						for (int k = 0 ; k < len; k ++){
							log(a_container, Array.get(object,k),arrClass,fieldName, a_depth + 1);
						}

					}else{
						log(a_container, object, fields[j].getType(),fieldName, a_depth + 1);
					}
				}catch(Exception e){

				}
			}
		}
	}

	static void log(ObjectContainer a_container, Object a_object, Class a_Class, String a_fieldName, int a_depth){
		if(a_object != null){
			if(a_container.isStored(a_object)){
				if(a_container.isActive(a_object)){
					log(a_depth, a_fieldName, "");
					log(a_container, a_object, a_depth);
				}
				return;
			}else{
				log(a_depth, a_fieldName, a_object.toString());
			}
		}
	}

    public static void log (String a_msg) {
		if(! silent){
			System.out.println(a_msg);
		}
    }

    public static void log (int indent, String a_property, String a_value) {
        for (int i = 0; i < indent; i++) {
            a_property = "\t" + a_property;
        }
        log(a_property, a_value);
    }

    public static void log (String a_property, String a_value) {
        if (a_value == null)
            a_value = "[NULL]";
        log(a_property + ": " + a_value);
    }

    public static void log (boolean a_true) {
        if (a_true)
            log("true");
        else
            log("false");
    }

    public static void log (byte[] bytes) {
        log(new String(bytes));
    }

    public static void log (Integer i) {
        log(i.toString());
    }

    public static void log (int i) {
        log(new Integer(i));
    }

    public static void log (Long l) {
        log(l.toString());
    }

    public static void log (long l) {
        log(new Long(l));
    }

    public static void log (Double d) {
        log(d.toString());
    }

    public static void log (double d) {
        log(new Double(d));
    }

    public static void log (Exception e, Object in, String msg) {
        String l_msg;
        if (e != null) {
            l_msg = "!!! " + e.getClass().getName();
            String l_exMsg = e.getMessage();
            if (l_exMsg != null) {
                l_msg += " " + l_exMsg;
            }
        }
        else {
            l_msg = "!!!Exception log";
        }
        if (in != null) {
            l_msg += " in " + in.getClass().getName();
        }
        if (msg != null) {
            l_msg += " " + msg;
        }
        log(l_msg);
    }







}
