package com.mongodb.memphis.config;

import java.util.List;

import org.bson.BsonDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.memphis.util.StringUtils;

public abstract class Config {

	protected transient final Logger logger = LoggerFactory.getLogger(getClass());
	protected transient Config parent;
	protected transient int depth;
	protected boolean disabled = false;
	protected String name;
	protected String database;
	protected Collection collection;

	public final String getDatabase() {
		if (database == null) {
			database = parent.getDatabase();
		}
		return database;
	}

	public final Collection getCollection() {
		if (collection == null) {
			collection = parent.getCollection();
		}
		return collection;
	}

	public MongoDatabase getMongoDatabase() {
		return getMongoClient().getDatabase(getDatabase());
	}

	public MongoCollection<BsonDocument> getMongoCollection() {
		return getCollection().getMongoCollection(getMongoDatabase());
	}

	public void initialise() {
	}

	protected final void initialiseHierarchy(Config parent, int depth) {
		this.parent = parent;
		this.depth = depth;
		if (getChildren() != null) {
			for (Config child : getChildren()) {
				child.initialiseHierarchy(this, depth+1);
			}
		}
	}

	public List<? extends Config> getChildren() {
		return null;
	}

	public MongoClient getMongoClient() {
		return parent.getMongoClient();
	}

	public String getName() {
		return name != null ? name : "";
	}

	public final void execute() {
		info("{} {} starting", getClass().getSimpleName(), getName());

		long startTime = System.currentTimeMillis();

		if (!disabled && getFilter().accept(this)) {
			executeInternal();
		}

		long totalTime = System.currentTimeMillis() - startTime;

		info("{} {} completed in {}", getClass().getSimpleName(), getName(), StringUtils.prettifyTime(totalTime));
	}

	protected void info(String format, Object... arguements) {
		logger.info(indent(format), arguements);
	}

	private String indent(String s) {
		for (int i=0; i<depth; i++) {
			s = "  " + s;
		}
		return s;
	}

	protected Config getParent() {
		return parent;
	}

	protected Root getRoot() {
		return parent.getRoot();
	}

	protected Filter getFilter() {
		return parent.getFilter();
	}

	protected abstract void executeInternal();

}

@@ -1365,17 +1365,19 @@
 s, depth
-+
+ + 
 1);%0A%09%09%09%7D
@@ -1625,16 +1625,64 @@
 ute() %7B%0A
+%09%09if (!disabled && getFilter().accept(this)) %7B%0A%09
 %09%09info(%22
@@ -1737,24 +1737,25 @@
 Name());%0A%0A%09%09
+%09
 long startTi
@@ -1790,56 +1790,8 @@
 s();
-%0A%0A%09%09if (!disabled && getFilter().accept(this)) %7B
 %0A%09%09%09
@@ -1810,20 +1810,16 @@
 nal();%0A%09
-%09%7D%0A%0A
 %09%09long t
@@ -1870,16 +1870,17 @@
 tTime;%0A%0A
+%09
 %09%09info(%22
@@ -1976,24 +1976,28 @@
 otalTime));%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09protect
@@ -2146,14 +2146,18 @@
 nt i
-=
+ = 
 0; i
-%3C
+ %3C 
 dept

improve output msg