/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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.
 */

import java.io.Serializable;
import java.io.IOException;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.BufferedInputStream;
import java.io.ObjectOutputStream;
import java.io.BufferedOutputStream;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import java.util.Arrays;
import java.nio.charset.Charset;

/**
 * Root of our data model.
 */
public class Root implements Serializable {

    private static final long serialVersionUID = 0;

    /** pid -> Proc */
    final Map<Integer, Proc> processes = new HashMap<Integer, Proc>();

    /** Class name -> LoadedClass */
    final Map<String, LoadedClass> loadedClasses
            = new HashMap<String, LoadedClass>();

//    MemoryUsage baseline = MemoryUsage.baseline();
    MemoryUsage baseline = MemoryUsage.NOT_AVAILABLE;

    /**
     * Records class loads and initializations.
     */
    void indexClassOperation(Record record) {
        Proc process = processes.get(record.pid);

        // Ignore dexopt output. It loads applications classes through the
        // system class loader and messes us up.
        if (record.processName.equals("dexopt")) {
            return;
        }

        String name = record.className;
        LoadedClass loadedClass = loadedClasses.get(name);
        Operation o = null;

        switch (record.type) {
            case START_LOAD:
            case START_INIT:
                if (loadedClass == null) {
                    loadedClass = new LoadedClass(
                            name, record.classLoader == 0);
                    if (loadedClass.systemClass) {
                        // Only measure memory for classes in the boot
                        // classpath.
//                        loadedClass.measureMemoryUsage();
                    }
                    loadedClasses.put(name, loadedClass);
                }
                break;

            case END_LOAD:
            case END_INIT:
                o = process.endOperation(record.tid, record.className,
                        loadedClass, record.time);
                if (o == null) {
                    return;
                }
        }

        switch (record.type) {
            case START_LOAD:
                process.startOperation(record.tid, loadedClass, record.time,
                        Operation.Type.LOAD);
                break;

            case START_INIT:
                process.startOperation(record.tid, loadedClass, record.time,
                        Operation.Type.INIT);
                break;

            case END_LOAD:
                loadedClass.loads.add(o);
                break;

            case END_INIT:
                loadedClass.initializations.add(o);
                break;
        }
    }

    /**
     * Indexes information about the process from the given record.
     */
    void indexProcess(Record record) {
        Proc proc = processes.get(record.pid);

        if (proc == null) {
            // Create a new process object.
            Proc parent = processes.get(record.ppid);
            proc = new Proc(parent, record.pid);
            processes.put(proc.id, proc);
            if (parent != null) {
                parent.children.add(proc);
            }
        }

        proc.setName(record.processName);
    }

    /**
     * Writes this graph to a file.
     */
    void toFile(String fileName) throws IOException {
        FileOutputStream out = new FileOutputStream(fileName);
        ObjectOutputStream oout = new ObjectOutputStream(
                new BufferedOutputStream(out));

        System.err.println("Writing object model...");

        oout.writeObject(this);

        oout.close();

        System.err.println("Done!");
    }

    /**
     * Reads Root from a file.
     */
    static Root fromFile(String fileName)
            throws IOException, ClassNotFoundException {
        FileInputStream fin = new FileInputStream(fileName);
        ObjectInputStream oin = new ObjectInputStream(
                new BufferedInputStream(fin));

        Root root = (Root) oin.readObject();

        oin.close();

        return root;
    }
}
