package hr.tis.mgw.client.samples.send;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.StringTokenizer;

public abstract class AbstractSamples {

	public static final String MM2_URL = "mm2.service-url";
	public static final String MM2_USERNAME = "mm2.username";
	public static final String MM2_PASSWORD = "mm2.password";

	public static final String CM2_URL = "cm2.service-url";
	public static final String CM2_USERNAME = "cm2.username";
	public static final String CM2_PASSWORD = "cm2.password";

	public static final String LM2_URL = "lm2.service-url";
	public static final String LM2_USERNAME = "lm2.username";
	public static final String LM2_PASSWORD = "lm2.password";

	public static final String RUN_EXAMPLE = "true";
	public static final String EXAMPLE_1 = "example.1";
	public static final String EXAMPLE_2 = "example.2";
	public static final String EXAMPLE_3 = "example.3";

	/*
	 * Read and show properties from configuration file
	 */
	public Properties readAndShowProperties(String defaultFileName, String[] args) {
		String filename = propertiesFileName(defaultFileName, args);
		Properties prop = readPropertiesFromFile(filename);
		showProperties(prop);

		return prop;
	}

	/*
	 * Determine properties filename.
	 * Use default filename if not specified in arguments.
	 */
	public String propertiesFileName(String defaultFileName, String[] args) {
		String filename = defaultFileName;
		if (args.length > 0) {
			filename = args[0];
		}
		return filename;
	}

	/*
	 * Read properties from file defined with filename.
	 * In case of error throw Runtime Exception.
	 */
	public Properties readPropertiesFromFile(String filename) {
		System.out.println("Reading properties from file: " + filename);
		File file = new File(filename);
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
			Properties prop = new Properties();
			prop.load(bis);

			return prop;
		}
		catch (FileNotFoundException e) {
			System.err.println("File not found: " + filename);
			throw new RuntimeException(e);
		}
		catch (IOException e) {
			System.err.println("Can't read content of file: " + filename);
			throw new RuntimeException(e);
		}
	}

	/*
	 * Display Properties on system out
	 */
	public void showProperties(Properties prop) {
		System.out.println();
		System.out.println("-------------   SAMPLE PROPERTIES   -------------");
		prop.list(System.out);
		System.out.println();
	}

	/*
	 * Split property on ',' and return String[] of values
	 */
	public String[] arrayFromPropertyList(String value) {
		ArrayList values = new ArrayList();
		StringTokenizer st = new StringTokenizer(value, " \t,;");
		while (st.hasMoreTokens()) {
			values.add(st.nextToken());
		}
		String[] res = new String[0];
		return (String[]) values.toArray(res);
	}

	/*
	 * Join string array into one string
	 */
	public String stringArrayToString(String[] values) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < values.length; i++) {
			sb.append(values[i]);
			if (i < values.length - 1) {
				sb.append(", ");
			}
		}
		return sb.toString();
	}

	/*
	 * File binary content from filename
	 */
	public byte[] fileBinaryContent(String filename) {
		System.out.println("Reading content from file: " + filename);
		File file = new File(filename);
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			byte[] buf = new byte[4096];
			int len;
			while ((len = bis.read(buf)) > 0) {
				baos.write(buf);
			}

			return baos.toByteArray();
		}
		catch (FileNotFoundException e) {
			System.err.println("File not found: " + filename);
			throw new RuntimeException(e);
		}
		catch (IOException e) {
			System.err.println("Can't read content of file: " + filename);
			throw new RuntimeException(e);
		}
	}

	/*
	 * Wait for some time
	 */
	public synchronized void sleep(long timeout) {
		try {
			this.wait(timeout);
		}
		catch (InterruptedException e) {
		}
	}
}
