/*
 * 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.server.util;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.PrintStream;
import java.util.Base64;

import org.apache.accumulo.core.cli.ConfigOpts;
import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;

import com.beust.jcommander.Parameter;

public class DumpZookeeper {

  private static ZooReaderWriter zk = null;

  private static class Encoded {
    public String encoding;
    public String value;

    Encoded(String e, String v) {
      encoding = e;
      value = v;
    }
  }

  static class Opts extends ConfigOpts {
    @Parameter(names = {"-r", "-root", "--root"},
        description = "Root ZooKeeper directory to start dump at")
    String root = "/";
    @Parameter(names = {"-x", "-xml", "--xml"},
        description = "Output dump as XML (instead of human readable")
    boolean xml = false;
  }

  public static void main(String[] args) throws KeeperException, InterruptedException {
    Opts opts = new Opts();
    opts.parseArgs(DumpZookeeper.class.getName(), args);

    PrintStream out = System.out;
    zk = new ZooReaderWriter(opts.getSiteConfiguration());
    if (opts.xml) {
      writeXml(out, opts.root);
    } else {
      writeHumanReadable(out, opts.root);
    }
  }

  private static void writeXml(PrintStream out, String root)
      throws KeeperException, InterruptedException {
    write(out, 0, "<dump root='%s'>", root);
    for (String child : zk.getChildren(root)) {
      if (!child.equals("zookeeper")) {
        childXml(out, root, child, 1);
      }
    }
    write(out, 0, "</dump>");
  }

  private static void childXml(PrintStream out, String root, String child, int indent)
      throws KeeperException, InterruptedException {
    String path = root + "/" + child;
    if (root.endsWith("/")) {
      path = root + child;
    }
    Stat stat = zk.getStatus(path);
    if (stat == null) {
      return;
    }
    String type = "node";
    if (stat.getEphemeralOwner() != 0) {
      type = "ephemeral";
    }
    if (stat.getNumChildren() == 0) {
      if (stat.getDataLength() == 0) {
        write(out, indent, "<%s name='%s'/>", type, child);
      } else {
        Encoded value = value(path);
        write(out, indent, "<%s name='%s' encoding='%s' value='%s'/>", type, child, value.encoding,
            value.value);
      }
    } else {
      if (stat.getDataLength() == 0) {
        write(out, indent, "<%s name='%s'>", type, child);
      } else {
        Encoded value = value(path);
        write(out, indent, "<%s name='%s' encoding='%s' value='%s'>", type, child, value.encoding,
            value.value);
      }
      for (String c : zk.getChildren(path)) {
        childXml(out, path, c, indent + 1);
      }
      write(out, indent, "</node>");
    }
  }

  private static Encoded value(String path) throws KeeperException, InterruptedException {
    byte[] data = zk.getData(path);
    for (byte element : data) {
      // does this look like simple ascii?
      if (element < ' ' || element > '~') {
        return new Encoded("base64", Base64.getEncoder().encodeToString(data));
      }
    }
    return new Encoded(UTF_8.name(), new String(data, UTF_8));
  }

  private static void write(PrintStream out, int indent, String fmt, Object... args) {
    for (int i = 0; i < indent; i++) {
      out.print("  ");
    }
    out.println(String.format(fmt, args));
  }

  private static void writeHumanReadable(PrintStream out, String root)
      throws KeeperException, InterruptedException {
    write(out, 0, "%s:", root);
    for (String child : zk.getChildren(root)) {
      if (!child.equals("zookeeper")) {
        childHumanReadable(out, root, child, 1);
      }
    }
  }

  private static void childHumanReadable(PrintStream out, String root, String child, int indent)
      throws KeeperException, InterruptedException {
    String path = root + "/" + child;
    if (root.endsWith("/")) {
      path = root + child;
    }
    Stat stat = zk.getStatus(path);
    if (stat == null) {
      return;
    }
    String node = child;
    if (stat.getEphemeralOwner() != 0) {
      node = "*" + child + "*";
    }
    if (stat.getDataLength() == 0) {
      write(out, indent, "%s:", node);
    } else {
      write(out, indent, "%s:  %s", node, value(path).value);
    }
    if (stat.getNumChildren() > 0) {
      for (String c : zk.getChildren(path)) {
        childHumanReadable(out, path, c, indent + 1);
      }
    }
  }
}
