/*
 * 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;
  final 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 {
    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();
    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);
    }
  }
}
