// Path: src/main/java/tech/pinto/tools/LogAppender.java
// public class LogAppender extends AppenderBase<ILoggingEvent> {
// public static ArrayBlockingQueue<String> LOG = new  ArrayBlockingQueue<String>(1000);
//   static int DEFAULT_LIMIT = 100000;
//   int counter = 0;
//   int limit = DEFAULT_LIMIT;
//   
//   PatternLayoutEncoder encoder;
//   
//   public void setLimit(int limit) {
//     this.limit = limit;
//   }
// 
//   public int getLimit() {
//     return limit;
//   }
//   
//   @Override
//   public void start() {
//     if (this.encoder == null) {
//       addError("No encoder set for the appender named ["+ name +"].");
//       return;
//     }
//     
//     try {
//       encoder.init(new OutputStream()
//       {
//           private StringBuilder string = new StringBuilder();
//           @Override
//           public void write(int b) throws IOException {
//         	  if(((char)b) == '\n') {
//         		  if(LOG.remainingCapacity() == 0) {
//         			  LOG.remove();
//         		  } else {
//         			  LOG.add(string.toString());
//         			  string.setLength(0);
//         		  }
//         	  } else {
//         		  this.string.append((char) b );
//         	  }
//           }
// 
//           public String toString(){
//               return this.string.toString();
//           }
//       });
//     } catch (IOException e) {
//     	e.printStackTrace();
//     }
//     super.start();
//   }
// 
//   public void append(ILoggingEvent event) {
//     if (counter >= limit) {
//       return;
//     }
//     try {
//       this.encoder.doEncode(event);
//     } catch (IOException e) {
//     	e.printStackTrace();
//     }
// 
//     counter++;
//   }
// 
//   public PatternLayoutEncoder getEncoder() {
//     return encoder;
//   }
// 
//   public void setEncoder(PatternLayoutEncoder encoder) {
//     this.encoder = encoder;
//   }
// }


import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import jline.console.ConsoleReader;
import tech.pinto.tools.LogAppender;

	private boolean trace = false;

	public Console(Pinto pinto, int port, String build, Runnable...shutdownCommands) {
		this.pinto = pinto;
		this.port = port;
		this.build = build;
		this.shutdownCommands = shutdownCommands;
	}

	@Override
	public void run() {
		try {
			NumberFormat nf = NumberFormat.getInstance();
			nf.setMinimumFractionDigits(4);
			nf.setMaximumFractionDigits(8);
			ConsoleReader reader = new ConsoleReader();
			reader.setPrompt("pinto> ");
			reader.addCompleter(pinto.getNamespace());
			String line;
			PrintWriter out = new PrintWriter(reader.getOutput());
			out.println("Pinto (build: " + build + ")");
			out.println("Server started on http://127.0.0.1:" + port);
			out.println("For pinto help type \"help\".  To quit type \"\\q\". To show other console options type \"\\help\".");

			while ((line = reader.readLine()) != null) {
				if (line.indexOf("\\") == 0) {
					if(line.startsWith("\\q")) {
						Arrays.stream(shutdownCommands).forEach(r -> r.run());
						return;
					} else if(line.startsWith("\\log")) {

// Path: src/main/java/tech/pinto/tools/LogAppender.java
// public class LogAppender extends AppenderBase<ILoggingEvent> {
// public static ArrayBlockingQueue<String> LOG = new  ArrayBlockingQueue<String>(1000);
//   static int DEFAULT_LIMIT = 100000;
//   int counter = 0;
//   int limit = DEFAULT_LIMIT;
//   
//   PatternLayoutEncoder encoder;
//   
//   public void setLimit(int limit) {
//     this.limit = limit;
//   }
// 
//   public int getLimit() {
//     return limit;
//   }
//   
//   @Override
//   public void start() {
//     if (this.encoder == null) {
//       addError("No encoder set for the appender named ["+ name +"].");
//       return;
//     }
//     
//     try {
//       encoder.init(new OutputStream()
//       {
//           private StringBuilder string = new StringBuilder();
//           @Override
//           public void write(int b) throws IOException {
//         	  if(((char)b) == '\n') {
//         		  if(LOG.remainingCapacity() == 0) {
//         			  LOG.remove();
//         		  } else {
//         			  LOG.add(string.toString());
//         			  string.setLength(0);
//         		  }
//         	  } else {
//         		  this.string.append((char) b );
//         	  }
//           }
// 
//           public String toString(){
//               return this.string.toString();
//           }
//       });
//     } catch (IOException e) {
//     	e.printStackTrace();
//     }
//     super.start();
//   }
// 
//   public void append(ILoggingEvent event) {
//     if (counter >= limit) {
//       return;
//     }
//     try {
//       this.encoder.doEncode(event);
//     } catch (IOException e) {
//     	e.printStackTrace();
//     }
// 
//     counter++;
//   }
// 
//   public PatternLayoutEncoder getEncoder() {
//     return encoder;
//   }
// 
//   public void setEncoder(PatternLayoutEncoder encoder) {
//     this.encoder = encoder;
//   }
// }


// Path: src/main/java/tech/pinto/Console.java
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import jline.console.ConsoleReader;
import tech.pinto.tools.LogAppender;

	private boolean trace = false;

	public Console(Pinto pinto, int port, String build, Runnable...shutdownCommands) {
		this.pinto = pinto;
		this.port = port;
		this.build = build;
		this.shutdownCommands = shutdownCommands;
	}

	@Override
	public void run() {
		try {
			NumberFormat nf = NumberFormat.getInstance();
			nf.setMinimumFractionDigits(4);
			nf.setMaximumFractionDigits(8);
			ConsoleReader reader = new ConsoleReader();
			reader.setPrompt("pinto> ");
			reader.addCompleter(pinto.getNamespace());
			String line;
			PrintWriter out = new PrintWriter(reader.getOutput());
			out.println("Pinto (build: " + build + ")");
			out.println("Server started on http://127.0.0.1:" + port);
			out.println("For pinto help type \"help\".  To quit type \"\\q\". To show other console options type \"\\help\".");

			while ((line = reader.readLine()) != null) {
				if (line.indexOf("\\") == 0) {
					if(line.startsWith("\\q")) {
						Arrays.stream(shutdownCommands).forEach(r -> r.run());
						return;
					} else if(line.startsWith("\\log")) {

						while(!LogAppender.LOG.isEmpty()) {
