package query_processing.hospital;

import java.sql.*;
import java.io.*;
import uk.ac.ic.doc.automed.*;
import uk.ac.ic.doc.automed.reps.*;
import uk.ac.ic.doc.automed.wrappers.*;

/**
 * This application provides an example for the BAV query processing and update
 * processing in AutoMed. This example has been adapted from the following
 * paper:
 * <pre>
 *   [MP03] Peter McBrien and Alexandra Poulovassilis. Defining peer­to­peer 
 *   data integration using both as view rules. In DBISP2P, pages 91--107, 2003. 
 * </pre>
 * 
 * The exact definition of the schemas of the three databases is given in the
 * file HospitalSchema.txt in SQL92 format.
 * 
 * @author <a href="mailto:sandeep@dcs.bbk.ac.uk">Sandeep Mittal</a>
 */
public class HospitalDBWrapping {
    static String username = "postgres";

    static String password = "manager";

    static String driver = "org.postgresql.Driver";

    static String urlbase = "jdbc:postgresql://localhost/";

    static Model sql92 = null;

    static Construct table = null;

    static Construct column = null;

    static Construct pk = null;

    static Construct fk = null;

    static SQLWrapperFactory wf;

    static String schemaChoice = null;

    private HospitalDBWrapping() {

    }

    public static void main(String[] args) {
        readArgs(args);
        try {
            System.out.println("AutoMed: Query and Update processing: "
                    + "Hospital Database Registration");

            // Wrap using SQL Wrapper
            wf = new SQLWrapperFactory();
            // Set the wrapper factory features
            wf.setFeatures(SQLWrapperFactory.PRIMARY_KEY);
            wf.setFeatures(SQLWrapperFactory.FOREIGN_KEY);
            wf.setFeatures(SQLWrapperFactory.DATA_TYPE);
            wf.setFeatures(SQLWrapperFactory.DATA_SIZE);
            wf.setFeatures(SQLWrapperFactory.NULL_CONSTRAINT);

            if (schemaChoice == null || "hs1".equals(schemaChoice))
                wrapSchema(username, password, driver, urlbase, wf, "hs1", "hs1");
            if (schemaChoice == null || "hs2".equals(schemaChoice))
                wrapSchema(username, password, driver, urlbase, wf, "hs2", "hs2");
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        } catch (AutoMedException ame) {
            ame.printStackTrace();
        } catch (Throwable t) {
            System.err.println(t.toString());
            t.printStackTrace();
        }
    }

    public static Schema wrapSchema(String username, String password,
            String driver, String urlbase, SQLWrapperFactory wf, String db,
            String name) throws Exception {

        // If schema exists, retract those from the repository.
        // AutoMed oriented schema
        if (Schema.exists(name))
            Schema.getSchema(name).retract();
        // Datasource oriented schema
        String sourceName = name + "_src";
        if (Schema.exists(sourceName))
            Schema.getSchema(sourceName).retract();

        // Get the Source oriented schema
        AutoMedWrapper sw = AutoMedWrapper.selectNewAutoMedWrapper(username,
                password, null, driver, urlbase + db, sourceName, wf);
        Schema sourceSchema = sw.getSchema();
        banner(sourceSchema.getName());
        sourceSchema.listSchema();

        // Generate an AutoMed oriented schema
        Schema s = sw.newAutoMedSchema(name);
        banner(s.getName());
        s.listSchema();

        return s;
    }

    static void printHelp() {
        System.out.println("Usage: HospitalDBWrapping [ options ]\n"
                + "  -debug <0-10>         set debug level\n"
                + "  -url <dbURL>          URL where DB located\n"
                + "  -driver <jdbcDriverClass>\n" + "  -user <user>\n"
                + "  -schema <schema name>\n" + "  -password <password>\n");
    }

    public static void readArgs(String[] args) {
        int i = 0;

        try {
            while (i < args.length) {
                if (args[i].charAt(0) != '-') {
                    System.out.println("Error at " + args[i] + "\n");
                    printHelp();
                    System.exit(10);
                } else if (args[i].startsWith("-debug"))
                    STR.setDebugLevel(Integer.parseInt(args[++i]));
                else if (args[i].startsWith("-url"))
                    urlbase = args[++i];
                else if (args[i].startsWith("-help"))
                    printHelp();
                else if (args[i].startsWith("-driver"))
                    driver = args[++i];
                else if (args[i].startsWith("-user"))
                    username = args[++i];
                else if (args[i].startsWith("-schema"))
                    schemaChoice = args[++i];
                else if (args[i].startsWith("-password"))
                    password = args[++i];
                ++i;
            }
            if (STR.atDebugLevel(5))
                System.out.println("Finished reading arguments, "
                        + "about to read database");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("You didn't supply an argument to the "
                    + args[i - 1] + " option!");
            printHelp();
            System.exit(10);
        }
    }

    public static void banner(String title) {
        int len = title.length();
        String stars = "**********************************************"
                + "*********************************";
        int slen = stars.length();

        System.out.println(stars);
        if (len > slen - 4)
            System.out.println(title);
        else
            System.out.println(stars.substring(0, (slen - len) / 2 - 1) + " "
                    + title + (len % 2 == 0 ? " " : "  ")
                    + stars.substring(0, (slen - len) / 2));
        System.out.println(stars);
    }
}


