/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.jackrabbit.oak.explorer;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Maps.newTreeMap;
import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.newTreeSet;
import static com.google.common.escape.Escapers.builder;
import static java.util.Collections.sort;
import static javax.jcr.PropertyType.BINARY;
import static javax.jcr.PropertyType.STRING;
import static javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION;
import static org.apache.commons.io.FileUtils.byteCountToDisplaySize;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.commons.json.JsopBuilder.prettyPrint;
import static org.apache.jackrabbit.oak.json.JsopDiff.diffToJsop;

import java.awt.*;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;

class NodeStoreTree extends JPanel implements TreeSelectionListener, Closeable {

    private static final long serialVersionUID = 1L;

    private final static int MAX_CHAR_DISPLAY = Integer.getInteger("max.char.display", 60);

    private static final String newline = "\n";

    private static void printGcRoots(StringBuilder sb, Map<UUID, Set<Entry<UUID, String>>> links, UUID uuid, String space, String inc) {
        Set<Entry<UUID, String>> roots = links.remove(uuid);

        if (roots == null || roots.isEmpty()) {
            return;
        }

        // TODO is sorting by file name needed?
        for (Entry<UUID, String> r : roots) {
            sb.append(space).append(r.getKey()).append("[").append(r.getValue()).append("]").append(newline);
            printGcRoots(sb, links, r.getKey(), space + inc, inc);
        }
    }

    private static void printPaths(List<String> paths, StringBuilder sb) {
        if (paths.isEmpty()) {
            return;
        }

        sb.append("Repository content references:").append(newline);

        for (String p : paths) {
            sb.append(p).append(newline);
        }
    }

    private static void printPropertyState(ExplorerBackend store, PropertyState state, String parentFile, StringBuilder b) {
        if (store.isPersisted(state)) {
            printRecordId(store.getRecordId(state), store.getFile(state), parentFile, b);
        } else {
            printSimpleClassName(state, b);
        }
    }

    private static void printNodeState(ExplorerBackend store, NodeState state, String parentTarFile, StringBuilder b) {
        if (store.isPersisted(state)) {
            printRecordId(store.getRecordId(state), store.getFile(state), parentTarFile, b);
        } else {
            printSimpleClassName(state, b);
        }
    }

    private static void printRecordId(String recordId, String file, String parentFile, StringBuilder l) {
        l.append(" (").append(recordId);

        if (file != null && !file.equals(parentFile)) {
            l.append(" in ").append(file);
        }

        l.append(")");
    }

    private static void printSimpleClassName(Object o, StringBuilder l) {
        l.append(" (").append(o.getClass().getSimpleName()).append(")");
    }

    private final ExplorerBackend backend;

    private Map<String, Set<UUID>> index;

    private DefaultTreeModel treeModel;

    private final JTree tree;

    private final JTextArea log;

    private Map<String, Long[]> sizeCache;

    private final boolean skipSizeCheck;

    NodeStoreTree(ExplorerBackend backend, JTextArea log, boolean skipSizeCheck)
            throws IOException {
        super(new GridLayout(1, 0));
        this.backend = backend;
        this.log = log;
        this.skipSizeCheck = skipSizeCheck;

        tree = new JTree();
        tree.getSelectionModel().setSelectionMode(SINGLE_TREE_SELECTION);
        tree.setShowsRootHandles(true);
        tree.addTreeSelectionListener(this);
        tree.setExpandsSelectedPaths(true);

        refreshStore();
        refreshModel();

        JScrollPane scrollPane = new JScrollPane(tree);
        add(scrollPane);
    }

    private void refreshStore() throws IOException {
        backend.open();
    }

    private void refreshModel() {
        index = backend.getTarReaderIndex();
        sizeCache = newHashMap();
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
                new NamePathModel("/", "/", backend.getHead(), sizeCache,
                        skipSizeCheck, backend), true);
        treeModel = new DefaultTreeModel(rootNode);
        addChildren(rootNode);
        tree.setModel(treeModel);
    }

    void reopen() throws IOException {
        close();
        refreshStore();
        refreshModel();
    }

    @Override
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
                .getLastSelectedPathComponent();
        if (node == null) {
            return;
        }
        // load child nodes:
        try {
            addChildren(node);
            updateStats(node);
        } catch (IllegalStateException ex) {
            ex.printStackTrace();

            StringBuilder sb = new StringBuilder();
            sb.append(ex.getMessage());
            sb.append(newline);

            NamePathModel model = (NamePathModel) node.getUserObject();
            NodeState state = model.getState();
            String recordId = backend.getRecordId(state);
            if (recordId != null) {
                sb.append("Record ");
                sb.append(recordId);
                sb.append(newline);
            }
            setText(sb.toString());
        }
    }

    private void setText(String s) {
        log.setText(s);
        log.setCaretPosition(0);
    }

    private void addChildren(DefaultMutableTreeNode parent) {
        NamePathModel model = (NamePathModel) parent.getUserObject();
        if (model.isLoaded()) {
            return;
        }

        List<NamePathModel> kids = newArrayList();
        for (ChildNodeEntry ce : model.getState().getChildNodeEntries()) {
            NamePathModel c = new NamePathModel(ce.getName(), concat(
                    model.getPath(), ce.getName()), ce.getNodeState(),
                    sizeCache, skipSizeCheck, backend);
            kids.add(c);
        }
        sort(kids);
        for (NamePathModel c : kids) {
            DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(c,
                    true);
            treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
        }
        model.loaded();
    }

    private void updateStats(DefaultMutableTreeNode parent) {
        NamePathModel model = (NamePathModel) parent.getUserObject();

        StringBuilder sb = new StringBuilder();
        sb.append(model.getPath());
        sb.append(newline);

        NodeState state = model.getState();
        String tarFile = "";

        if (backend.isPersisted(state)) {
            String recordId = backend.getRecordId(state);
            sb.append("Record ").append(recordId);
            tarFile = backend.getFile(state);
            if (tarFile != null) {
                sb.append(" in ").append(tarFile);
            }
            sb.append(newline);

            String templateId = backend.getTemplateRecordId(state);
            String f = backend.getTemplateFile(state);
            sb.append("TemplateId ");
            sb.append(templateId);
            if (f != null && !f.equals(tarFile)) {
                sb.append(" in ").append(f);
            }
            sb.append(newline);
        }

        sb.append("Size: ");
        sb.append("  direct: ");
        sb.append(byteCountToDisplaySize(model.getSize()[0]));
        sb.append(";  linked: ");
        sb.append(byteCountToDisplaySize(model.getSize()[1]));
        sb.append(newline);

        sb.append("Properties (count: ").append(state.getPropertyCount()).append(")");
        sb.append(newline);
        Map<String, String> propLines = newTreeMap();
        for (PropertyState ps : state.getProperties()) {
            StringBuilder l = new StringBuilder();
            l.append("  - ").append(ps.getName()).append(" = {").append(ps.getType()).append("} ");
            if (ps.getType().isArray()) {
                int count = ps.count();
                l.append("(count ").append(count).append(") [");

                String separator = ", ";
                int max = 50;
                if (ps.getType() == Type.BINARIES) {
                    separator = newline + "      ";
                    max = Integer.MAX_VALUE;
                    l.append(separator);
                }
                for (int i = 0; i < Math.min(count, max); i++) {
                    if (i > 0) {
                        l.append(separator);
                    }
                    l.append(toString(ps, i, tarFile));
                }
                if (count > max) {
                    l.append(", ... (").append(count).append(" values)");
                }
                if (ps.getType() == Type.BINARIES) {
                    l.append(separator);
                }
                l.append("]");

            } else {
                l.append(toString(ps, 0, tarFile));
            }
            printPropertyState(backend, ps, tarFile, l);
            propLines.put(ps.getName(), l.toString());
        }

        for (String l : propLines.values()) {
            sb.append(l);
            sb.append(newline);
        }

        sb.append("Child nodes (count: ").append(state.getChildNodeCount(Long.MAX_VALUE)).append(")");
        sb.append(newline);
        Map<String, String> childLines = newTreeMap();
        for (ChildNodeEntry ce : state.getChildNodeEntries()) {
            StringBuilder l = new StringBuilder();
            l.append("  + ").append(ce.getName());
            NodeState c = ce.getNodeState();
            printNodeState(backend, c, tarFile, l);
            childLines.put(ce.getName(), l.toString());
        }
        for (String l : childLines.values()) {
            sb.append(l);
            sb.append(newline);
        }

        if ("/".equals(model.getPath())) {
            sb.append("File Reader Index");
            sb.append(newline);

            for (String path : backend.getTarFiles()) {
                sb.append(path);
                sb.append(newline);
            }
            sb.append("----------");
        }

        setText(sb.toString());
    }

    private String toString(PropertyState ps, int index, String tarFile) {
        if (ps.getType().tag() == BINARY) {
            Blob b = ps.getValue(Type.BINARY, index);
            String info = "<";
            info += b.getClass().getSimpleName() + ";";
            info += "ref:" + safeGetReference(b) + ";";
            info += "id:" + b.getContentIdentity() + ";";
            info += safeGetLength(b) + ">";

            for (Entry<UUID, String> e : backend.getBulkSegmentIds(b).entrySet()) {
                info += newline + "        Bulk Segment Id " + e.getKey();
                if (e.getValue() != null && !e.getValue().equals(tarFile)) {
                    info += " in " + e.getValue();
                }
            }

            return info;
        } else if (ps.getType().tag() == STRING) {
            return displayString(ps.getValue(Type.STRING, index));
        } else {
            return ps.getValue(Type.STRING, index);
        }
    }

    private static String displayString(String value) {
        if (MAX_CHAR_DISPLAY > 0 && value.length() > MAX_CHAR_DISPLAY) {
            value = value.substring(0, MAX_CHAR_DISPLAY) + "... ("
                    + value.length() + " chars)";
        }
        String escaped = builder().setSafeRange(' ', '~')
                .addEscape('"', "\\\"").addEscape('\\', "\\\\").build()
                .escape(value);
        return '"' + escaped + '"';
    }

    private String safeGetReference(Blob b) {
        try {
            return b.getReference();
        } catch (IllegalStateException e) {
            // missing BlobStore probably
        }
        return "[BlobStore not available]";
    }

    private String safeGetLength(Blob b) {
        try {
            return byteCountToDisplaySize(b.length());
        } catch (IllegalStateException e) {
            // missing BlobStore probably
        }
        return "[BlobStore not available]";
    }

    void printTarInfo(String file) {
        if (file == null || file.length() == 0) {
            return;
        }
        StringBuilder sb = new StringBuilder();

        Set<UUID> uuids = newHashSet();
        for (Entry<String, Set<UUID>> e : index.entrySet()) {
            if (e.getKey().endsWith(file)) {
                sb.append("SegmentNodeState references to ").append(e.getKey());
                sb.append(newline);
                uuids = e.getValue();
                break;
            }
        }

        Set<UUID> inMem = intersection(backend.getReferencedSegmentIds(), uuids);
        if (!inMem.isEmpty()) {
            sb.append("In Memory segment references: ");
            sb.append(newline);
            sb.append(inMem);
            sb.append(newline);
        }

        List<String> paths = newArrayList();
        filterNodeStates(uuids, paths, backend.getHead(), "/", backend);
        printPaths(paths, sb);

        sb.append(newline);
        try {
            Map<UUID, Set<UUID>> graph = backend.getTarGraph(file);
            sb.append("Tar graph:").append(newline);
            for (Entry<UUID, Set<UUID>> entry : graph.entrySet()) {
                sb.append(entry.getKey()).append('=').append(entry.getValue())
                        .append(newline);
            }
            sb.append(newline);
        } catch (IOException e) {
            sb.append("Error getting tar graph:").append(e).append(newline);
        }

        setText(sb.toString());
    }

    void printSegmentReferences(String sid) {
        if (sid == null || sid.length() == 0) {
            return;
        }
        UUID id = null;
        try {
            id = UUID.fromString(sid.trim());
        } catch (IllegalArgumentException e) {
            setText(e.getMessage());
            return;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("References to segment ").append(id);
        sb.append(newline);
        for (Entry<String, Set<UUID>> e : index.entrySet()) {
            if (e.getValue().contains(id)) {
                sb.append("Tar file: ").append(e.getKey());
                sb.append(newline);
                break;
            }
        }

        List<String> paths = newArrayList();
        filterNodeStates(newHashSet(id), paths, backend.getHead(), "/", backend);
        printPaths(paths, sb);

        Map<UUID, Set<Entry<UUID, String>>> links = newHashMap();
        try {
            backend.getGcRoots(id, links);
        } catch (IOException e) {
            sb.append(newline);
            sb.append(e.getMessage());
        }
        if (!links.isEmpty()) {
            sb.append("Segment GC roots:");
            sb.append(newline);
            printGcRoots(sb, links, id, "  ", "  ");
        }

        setText(sb.toString());
    }

    private static void filterNodeStates(Set<UUID> uuids, List<String> paths, NodeState state, String path, ExplorerBackend store) {
        Set<String> localPaths = newTreeSet();
        for (PropertyState ps : state.getProperties()) {
            if (store.isPersisted(ps)) {
                String recordId = store.getRecordId(ps);
                UUID id = store.getSegmentId(ps);
                if (uuids.contains(id)) {
                    if (ps.getType().tag() == STRING) {
                        String val = "";
                        if (ps.count() > 0) {
                            // only shows the first value, do we need more?
                            val = displayString(ps.getValue(Type.STRING, 0));
                        }
                        localPaths.add(path + ps.getName() + " = " + val
                                + " [SegmentPropertyState<" + ps.getType()
                                + ">@" + recordId + "]");
                    } else {
                        localPaths.add(path + ps + " [SegmentPropertyState<"
                                + ps.getType() + ">@" + recordId + "]");
                    }

                }
                if (ps.getType().tag() == BINARY) {
                    // look for extra segment references
                    for (int i = 0; i < ps.count(); i++) {
                        Blob b = ps.getValue(Type.BINARY, i);
                        for (Entry<UUID, String> e : store.getBulkSegmentIds(b).entrySet()) {
                            if (!e.getKey().equals(id) && uuids.contains(e.getKey())) {
                                localPaths.add(path + ps
                                        + " [SegmentPropertyState<"
                                        + ps.getType() + ">@" + recordId + "]");
                            }
                        }
                    }
                }
            }
        }

        String stateId = store.getRecordId(state);
        if (uuids.contains(store.getSegmentId(state))) {
            localPaths.add(path + " [SegmentNodeState@" + stateId + "]");
        }

        String templateId = store.getTemplateRecordId(state);
        if (uuids.contains(store.getTemplateSegmentId(state))) {
            localPaths.add(path + "[Template@" + templateId + "]");
        }
        paths.addAll(localPaths);
        for (ChildNodeEntry ce : state.getChildNodeEntries()) {
            filterNodeStates(uuids, paths, ce.getNodeState(), path + ce.getName() + "/", store);
        }
    }

    void printDiff(String input) {
        StringBuilder sb = new StringBuilder();
        if (input == null || input.trim().length() == 0) {
            setText("Usage <recordId> <recordId> [<path>]");
            return;
        }

        String[] tokens = input.trim().split(" ");
        if (tokens.length != 2 && tokens.length != 3) {
            setText("Usage <recordId> <recordId> [<path>]");
            return;
        }
        NodeState node1;
        NodeState node2;
        try {
            node1 = backend.readNodeState(tokens[0]);
            node2 = backend.readNodeState(tokens[1]);
        } catch (IllegalArgumentException ex) {
            sb.append("Unknown argument: ");
            sb.append(input);
            sb.append(newline);
            sb.append("Error: ");
            sb.append(ex.getMessage());
            sb.append(newline);
            setText(sb.toString());
            return;
        }
        String path = "/";
        if (tokens.length == 3) {
            path = tokens[2];
        }

        for (String name : elements(path)) {
            node1 = node1.getChildNode(name);
            node2 = node2.getChildNode(name);
        }

        sb.append("SegmentNodeState diff ");
        sb.append(tokens[0]);
        sb.append(" vs ");
        sb.append(tokens[1]);
        sb.append(" at ");
        sb.append(path);
        sb.append(newline);
        sb.append("--------");
        sb.append(newline);
        sb.append(prettyPrint(diffToJsop(node1, node2)));
        setText(sb.toString());
    }

    boolean revert(String revision) {
        return safeRevert(revision, false);
    }

    private boolean safeRevert(String revision, boolean rollback) {
        String head = backend.getRecordId(backend.getHead());
        backend.setRevision(revision);
        try {
            refreshModel();
            if (!rollback) {
                setText("Switched head revision to " + revision);
            }
        } catch (Exception e) {
            StringBuilder sb = new StringBuilder();
            sb.append("Unable to switch head revision to ");
            sb.append(revision);
            sb.append(newline);
            sb.append("    ");
            sb.append(e.getMessage());
            sb.append(newline);
            sb.append("Will rollback to ");
            sb.append(head);
            setText(sb.toString());
            return safeRevert(head, true);
        }
        return !rollback;
    }

    void printPCMInfo() {
        setText(backend.getPersistedCompactionMapStats());
    }

    private static class NamePathModel implements Comparable<NamePathModel> {

        private final ExplorerBackend backend;
        private final String name;
        private final String path;
        private final boolean skipSizeCheck;

        private boolean loaded = false;

        private Long[] size = {-1L, -1L};

        NamePathModel(String name, String path, NodeState state, Map<String, Long[]> sizeCache, boolean skipSizeCheck, ExplorerBackend backend) {
            this.backend = backend;
            this.name = name;
            this.path = path;
            this.skipSizeCheck = skipSizeCheck;
            if (!skipSizeCheck && backend.isPersisted(state)) {
                this.size = exploreSize(state, sizeCache, backend);
            }
        }

        void loaded() {
            loaded = true;
        }

        boolean isLoaded() {
            return loaded;
        }

        @Override
        public String toString() {
            if (skipSizeCheck) {
                return name;
            }
            if (size[1] > 0) {
                return name + " (" + byteCountToDisplaySize(size[0]) + ";"
                        + byteCountToDisplaySize(size[1]) + ")";
            }
            if (size[0] > 0) {
                return name + " (" + byteCountToDisplaySize(size[0]) + ")";
            }
            return name;
        }

        public String getPath() {
            return path;
        }

        public NodeState getState() {
            return loadState();
        }

        private NodeState loadState() {
            NodeState n = backend.getHead();
            for (String p : elements(path)) {
                n = n.getChildNode(p);
            }
            return n;
        }

        @Override
        public int compareTo(NamePathModel o) {
            int s = size[0].compareTo(o.size[0]);
            if (s != 0) {
                return -1 * s;
            }
            s = size[1].compareTo(o.size[1]);
            if (s != 0) {
                return -1 * s;
            }
            if ("root".equals(name)) {
                return 1;
            } else if ("root".equals(o.name)) {
                return -1;
            }
            return name.compareTo(o.name);
        }

        public Long[] getSize() {
            return size;
        }
    }

    private static Long[] exploreSize(NodeState ns, Map<String, Long[]> sizeCache, ExplorerBackend store) {
        String key = store.getRecordId(ns);
        if (sizeCache.containsKey(key)) {
            return sizeCache.get(key);
        }
        Long[] s = {0L, 0L};

        List<String> names = newArrayList(ns.getChildNodeNames());

        if (names.contains("root")) {
            List<String> temp = newArrayList();
            int poz = 0;
            // push 'root' to the beginning
            for (String n : names) {
                if (n.equals("root")) {
                    temp.add(poz, n);
                    poz++;
                } else {
                    temp.add(n);
                }
            }
            names = temp;
        }

        for (String n : names) {
            NodeState k = ns.getChildNode(n);
            String ckey = store.getRecordId(k);
            if (sizeCache.containsKey(ckey)) {
                // already been here, record size under 'link'
                Long[] ks = sizeCache.get(ckey);
                s[1] = s[1] + ks[0] + ks[1];
            } else {
                Long[] ks = exploreSize(k, sizeCache, store);
                s[0] = s[0] + ks[0];
                s[1] = s[1] + ks[1];
            }
        }
        for (PropertyState ps : ns.getProperties()) {
            for (int j = 0; j < ps.count(); j++) {
                if (ps.getType().tag() == Type.BINARY.tag()) {
                    Blob b = ps.getValue(Type.BINARY, j);
                    boolean skip = store.isExternal(b);
                    if (!skip) {
                        s[0] = s[0] + b.length();
                    }
                } else {
                    s[0] = s[0] + ps.size(j);
                }
            }
        }
        sizeCache.put(key, s);
        return s;
    }

    @Override
    public void close() throws IOException {
        backend.close();
    }

}
