/*
 * 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.
 */

package com.android.hierarchyviewer.scene;

import com.android.ddmlib.IDevice;
import com.android.hierarchyviewer.device.DeviceBridge;
import com.android.hierarchyviewer.device.Window;

import org.openide.util.Exceptions;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Collections;
import java.util.Comparator;
import java.util.Stack;
import java.util.regex.Pattern;

public class ViewHierarchyLoader {
    @SuppressWarnings("empty-statement")
    public static ViewHierarchyScene loadScene(IDevice device, Window window) {
        ViewHierarchyScene scene = new ViewHierarchyScene();

        // Read the views tree
        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;

        String line;

        try {
            System.out.println("==> Starting client");

            socket = new Socket();
            socket.connect(new InetSocketAddress("127.0.0.1",
                    DeviceBridge.getDeviceLocalPort(device)));

            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            System.out.println("==> DUMP");

            out.write("DUMP " + window.encode());
            out.newLine();
            out.flush();

            Stack<ViewNode> stack = new Stack<ViewNode>();

            boolean setRoot = true;
            ViewNode lastNode = null;
            int lastWhitespaceCount = Integer.MAX_VALUE;

            while ((line = in.readLine()) != null) {
                if ("DONE.".equalsIgnoreCase(line)) {
                    break;
                }

                int whitespaceCount = countFrontWhitespace(line);
                if (lastWhitespaceCount < whitespaceCount) {
                    stack.push(lastNode);
                } else if (!stack.isEmpty()) {
                    final int count = lastWhitespaceCount - whitespaceCount;
                    for (int i = 0; i < count; i++) {
                        stack.pop();
                    }
                }

                lastWhitespaceCount = whitespaceCount;
                line = line.trim();
                int index = line.indexOf(' ');

                lastNode = new ViewNode();
                lastNode.name = line.substring(0, index);

                line = line.substring(index + 1);
                loadProperties(lastNode, line);

                scene.addNode(lastNode);

                if (setRoot) {
                    scene.setRoot(lastNode);
                    setRoot = false;
                }

                if (!stack.isEmpty()) {
                    final ViewNode parent = stack.peek();
                    final String edge = parent.name + lastNode.name;
                    scene.addEdge(edge);
                    scene.setEdgeSource(edge, parent);
                    scene.setEdgeTarget(edge, lastNode);
                    lastNode.parent = parent;
                    parent.children.add(lastNode);
                }
            }

            updateIndices(scene.getRoot());

        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                socket.close();
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        }

        System.out.println("==> DONE");

        return scene;
    }

    private static void updateIndices(ViewNode root) {
        if (root == null) return;

        root.computeIndex();

        for (ViewNode node : root.children) {
            updateIndices(node);
        }
    }

    private static int countFrontWhitespace(String line) {
        int count = 0;
        while (line.charAt(count) == ' ') {
            count++;
        }
        return count;
    }

    private static void loadProperties(ViewNode node, String data) {
        int start = 0;
        boolean stop;

        do {
            int index = data.indexOf('=', start);
            ViewNode.Property property = new ViewNode.Property();
            property.name = data.substring(start, index);

            int index2 = data.indexOf(',', index + 1);
            int length = Integer.parseInt(data.substring(index + 1, index2));
            start = index2 + 1 + length;
            property.value = data.substring(index2 + 1, index2 + 1 + length);

            node.properties.add(property);
            node.namedProperties.put(property.name, property);

            stop = start >= data.length();
            if (!stop) {
                start += 1;
            }
        } while (!stop);

        Collections.sort(node.properties, new Comparator<ViewNode.Property>() {
            public int compare(ViewNode.Property source, ViewNode.Property destination) {
                return source.name.compareTo(destination.name);
            }
        });

        node.decode();
    }
}
