/*
 * 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.accumulo.examples.dirlist;

import java.awt.BorderLayout;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.examples.filedata.FileDataQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beust.jcommander.Parameter;

/**
 * Provides a GUI for browsing the file system information stored in Accumulo.
 */
@SuppressWarnings("serial")
public class Viewer extends JFrame implements TreeSelectionListener, TreeExpansionListener {
  private static final Logger log = LoggerFactory.getLogger(Viewer.class);

  JTree tree;
  DefaultTreeModel treeModel;
  QueryUtil q;
  FileDataQuery fdq;
  String topPath;
  Map<String,DefaultMutableTreeNode> nodeNameMap;
  JTextArea text;
  JTextArea data;
  JScrollPane dataPane;

  public static class NodeInfo {
    private final String name;
    private final Map<String,String> data;

    public NodeInfo(String name, Map<String,String> data) {
      this.name = name;
      this.data = data;
    }

    public String getName() {
      return name;
    }

    public String getFullName() {
      String fn = data.get("fullname");
      if (fn == null)
        return name;
      return fn;
    }

    public Map<String,String> getData() {
      return data;
    }

    @Override
    public String toString() {
      return getName();
    }

    public String getHash() {
      for (String k : data.keySet()) {
        String[] parts = k.split(":");
        if (parts.length >= 2 && parts[1].equals("md5")) {
          return data.get(k);
        }
      }
      return null;
    }
  }

  public Viewer(AccumuloClient client, Opts opts) throws Exception {
    super("File Viewer");
    setSize(1000, 800);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    q = new QueryUtil(client, opts);
    fdq = new FileDataQuery(client, opts.dataTable, opts.auths);
    this.topPath = opts.path;
  }

  public void populate(DefaultMutableTreeNode node) throws TableNotFoundException {
    String path = ((NodeInfo) node.getUserObject()).getFullName();
    log.debug("listing " + path);
    for (Entry<String,Map<String,String>> e : q.getDirList(path).entrySet()) {
      log.debug("got child for " + node.getUserObject() + ": " + e.getKey());
      node.add(new DefaultMutableTreeNode(new NodeInfo(e.getKey(), e.getValue())));
    }
  }

  public void populateChildren(DefaultMutableTreeNode node) throws TableNotFoundException {
    @SuppressWarnings("unchecked")
    Enumeration<TreeNode> children = node.children();
    while (children.hasMoreElements()) {
      populate((DefaultMutableTreeNode) children.nextElement());
    }
  }

  public void init() throws TableNotFoundException {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(
        new NodeInfo(topPath, q.getData(topPath)));
    populate(root);
    populateChildren(root);

    treeModel = new DefaultTreeModel(root);
    tree = new JTree(treeModel);
    tree.addTreeExpansionListener(this);
    tree.addTreeSelectionListener(this);
    text = new JTextArea(getText(q.getData(topPath)));
    data = new JTextArea("");
    JScrollPane treePane = new JScrollPane(tree);
    JScrollPane textPane = new JScrollPane(text);
    dataPane = new JScrollPane(data);
    JSplitPane infoSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, textPane, dataPane);
    JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePane, infoSplitPane);
    mainSplitPane.setDividerLocation(300);
    infoSplitPane.setDividerLocation(150);
    getContentPane().add(mainSplitPane, BorderLayout.CENTER);
  }

  public static String getText(DefaultMutableTreeNode node) {
    return getText(((NodeInfo) node.getUserObject()).getData());
  }

  public static String getText(Map<String,String> data) {
    StringBuilder sb = new StringBuilder();
    for (String name : data.keySet()) {
      sb.append(name);
      sb.append(" : ");
      sb.append(data.get(name));
      sb.append('\n');
    }
    return sb.toString();
  }

  @Override
  public void treeExpanded(TreeExpansionEvent event) {
    try {
      populateChildren((DefaultMutableTreeNode) event.getPath().getLastPathComponent());
    } catch (TableNotFoundException e) {
      log.error("Could not find table.", e);
    }
  }

  @Override
  public void treeCollapsed(TreeExpansionEvent event) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
    @SuppressWarnings("unchecked")
    Enumeration<TreeNode> children = node.children();
    while (children.hasMoreElements()) {
      DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
      log.debug("removing children of " + ((NodeInfo) child.getUserObject()).getFullName());
      child.removeAllChildren();
    }
  }

  @Override
  public void valueChanged(TreeSelectionEvent e) {
    TreePath selected = e.getNewLeadSelectionPath();
    if (selected == null)
      return;
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) selected.getLastPathComponent();
    text.setText(getText(node));
    try {
      String hash = ((NodeInfo) node.getUserObject()).getHash();
      if (hash != null) {
        data.setText(fdq.getSomeData(hash, 10000));
      } else {
        data.setText("");
      }
    } catch (IOException e1) {
      log.error("Could not get data from FileDataQuery.", e1);
    }
  }

  static class Opts extends QueryUtil.Opts {
    @Parameter(names = "--dataTable")
    String dataTable = "dataTable";
  }

  public static void main(String[] args) throws Exception {
    Opts opts = new Opts();
    opts.parseArgs(Viewer.class.getName(), args);
    try (AccumuloClient client = opts.createAccumuloClient()) {
      Viewer v = new Viewer(client, opts);
      v.init();
      v.setVisible(true);
    }
  }
}
