package tableDefinition;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

import dataWarehousingTools.Timer;
import dataWarehousingTools.LogFile;
import dataWarehousingTools.MetadataConfiguration;
import dataWarehousingTools.DatabaseLogin;


public class TableDefinition
{
//	This version specifies everything through a configuration file,
//	with optional overrides through command-line parameters.
//	It does *not* use the XML configuration file and does *not* use the data quality database
//	There is a configuration file which is identified by the first argument.
//	The schema in the configuration file may be over-ridden by the second parameter, if present, and
//	the table in the configuration file may be over-ridden by the third parameter, if present

	public static void main(String[] args)
	{
		String configurationName;
		String configurationFile;
		MetadataConfiguration configuration;
		LogFile logFile;
		String outputDirectory;
		DatabaseLogin databaseLogin;
		Connection connection;
		DatabaseMetaData databaseMetaData;
		String databaseProduct = null;
    	String databaseVersion = null;
    	DatabaseEncoding databaseEncoding;
    	DatabaseSchemaTableList databaseSchemaTableList;
		String databaseName = "";
		String schemaName = "";
		String tableName = "";
		String encoding = "UNKNOWN";
		SchemaList schemaList = null;
		TableList tableList = null;
		ColumnList columnList;
        Timer timer;


        String schemaOverride = "";
		String tableOverride = "";		
		
		if ((args.length < 1) || (args.length > 3))
		{
			System.out.println("");
			System.out.println("Usage: TableDefinition configuration-file [schema-override [table-override]]");
			System.out.println("");
			System.out.println("    configuration: path of configuration file, always needed");
			System.out.println("    schema:        name of schema containing table definitions to be extracted, needed if table specified");
			System.out.println("    table:         name of table for which definition to be extracted");
			System.out.println("");
			System.out.println("If only configuration-file is specified, extract the definition of the table in the configuration-file.");
			System.out.println("If schema is not specified in configuration-file, and not overridden, generate list of schemas in this datatbase.");
			System.out.println("If table is not specified in configuration-file, and not overridden, generate 'create table ...' statement for all tables in this schema.");
			System.out.println("If schema and table are specified, generate 'create table ...'statement and script to unload the table, for this table.");
			System.out.println("");
			System.out.println("Documentation: https://www.thedatastudio.net/data_profiler_documentation.htm");
			System.exit(1);
		}

		timer = new Timer();

		configurationFile = new String(args[0]);
		
		if (args.length > 1)
			schemaOverride = new String(args[1]);
		if (args.length > 2)
			tableOverride = new String(args[2]);

		configuration = new MetadataConfiguration(configurationFile);
		
		outputDirectory = new String(configuration.getOutputDirectory());
		
		
		
		logFile = new LogFile(configuration, "TableDefinition_");
		logFile.logMessage("Configuration: " + configurationFile);
		
		databaseLogin = new DatabaseLogin(configurationFile);
		
		try
		{
		    connection = databaseLogin.getConnection();
		    
			try 
			{
				databaseMetaData = connection.getMetaData();
				databaseProduct = databaseMetaData.getDatabaseProductName();
				databaseVersion = databaseMetaData.getDatabaseProductVersion();
			} 
			catch (SQLException e1) 
			{
				logFile.logMessage(e1.getMessage());
				logFile.logMessage(e1.getStackTrace().toString());
			}

			databaseName = configuration.getDatabase();
			schemaName = new String(schemaOverride);
			if (schemaName.isEmpty())
				schemaName = configuration.getSchema();
			tableName = new String(tableOverride);
			if (tableName.isEmpty())
				tableName = configuration.getTable();
			
			if (databaseName.isEmpty())
			{
//				Print a list of databases on this connection
				System.out.println("List of databases not implemented yet");
				System.exit(0);
			}
			
			databaseEncoding = new DatabaseEncoding(connection, databaseProduct, databaseName);
			encoding = new String(DatabaseEncoding.getEncoding());
			logFile.logMessage("Database: " + databaseName + ", Version: " + databaseVersion +", Encoding: " + encoding);
			
			if (schemaName.isEmpty())
			{
//				Print list of schemas in the database
				schemaList = new SchemaList(connection, databaseName, outputDirectory, logFile);
				new PrintSchemasInDatabase(schemaList, outputDirectory, logFile);
				System.exit(0);
			}
			
			if (tableName.isEmpty())
			{
				tableList = new TableList(connection, databaseProduct, databaseName, schemaName, outputDirectory, logFile);
				new PrintTablesInSchema(tableList, outputDirectory, logFile);
			}
			else
			{
				logFile.logMessage("Database: " + databaseName + ", Schema: " + schemaName + ", Table: " + tableName);
				columnList = new ColumnList(databaseProduct, connection, databaseName, schemaName, tableName, logFile);
				new CheckDataTypes(tableName, columnList, logFile);
				new PrintColumnsInTable(tableName, columnList, outputDirectory, logFile);
				new GenerateCreateScript(tableName, columnList, outputDirectory);
				new GenerateUnloadDataScript(databaseProduct, schemaName, tableName, columnList, outputDirectory, logFile);
			}
			
			try 
			{
				connection.close();
			} 
			catch (SQLException e) 
			{
				e.printStackTrace();
			}
		}
		finally
		{
			logFile.Close();
			timer.end();
		}
	}
}
