/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package zapoctak;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author brecj6am
 */
public class Main {
    public static void createTable(String tableName, String[] columnNames) throws IOException
    {
        File F = new File(tableName + ".db");

        if ((columnNames.length == 0) || ((columnNames.length == 1) && (columnNames[0].equals(""))))
            throw new IOException("Zero column count.");

        if (F.exists())
        {
            throw new IOException("Table already exists.");
        }

        F.createNewFile();

        BufferedWriter BW = new BufferedWriter(new FileWriter(tableName + ".db"));

        for (int i = 0; i < columnNames.length; i++)
        {
            BW.append(columnNames[i]);
            if (i != columnNames.length - 1)
            {
                BW.append(";");
            }
        }
        BW.append("\n");

        BW.close();
    }

    public static void dropTable(String tableName) throws IOException
    {
        File F = new File(tableName + ".db");

        if (!F.exists())
        {
            throw new IOException("Table does not exist.");
        }

        F.delete();
    }

    public static void insertInto(String tableName, String[] values) throws IOException
    {
        BufferedReader BR = new BufferedReader(new FileReader(tableName + ".db"));
        String header = BR.readLine();
        BR.close();
        
        String[] columnNames = header.split(";");

        if (values.length != columnNames.length)
        {
            throw new IOException("Invalid column count.");
        }

        BufferedWriter BW = new BufferedWriter(new FileWriter(tableName + ".db", true));

        for (int i = 0; i < values.length; i++)
        {
            BW.write(values[i]);
            if (i != values.length - 1)
            {
                BW.write(";");
            }
        }
        BW.write("\n");

        BW.close();
    }

    public static int deleteFrom(String tableName, String columnName, String value) throws IOException
    {
        int deletedRows = 0;
        
        BufferedReader BR = new BufferedReader(new FileReader(tableName + ".db"));
        try
        {
            String header = BR.readLine();
            String[] columnNames = header.split(";");
            
            int columnIndex = -1;
            for (int i = 0; i < columnNames.length; i++)
            {
                if (columnNames[i].equals(columnName))
                    columnIndex = i;
            }

            if (columnIndex == -1)
                throw new IOException("Invalid column name.");

            String output = "";

            String line = BR.readLine();
            while (line != null)
            {
                String[] lineValues = line.split(";");
                if (lineValues.length < columnNames.length)
                {
                    String[] newLineValues = new String[columnNames.length];

                    for (int i = 0; i < newLineValues.length; i++)
                        newLineValues[i] = "";

                    for (int i = 0; i < lineValues.length; i++)
                        newLineValues[i] = lineValues[i];

                    lineValues = newLineValues;
                }

                if (lineValues[columnIndex].equals(value))
                {
                    // skip the row
                    deletedRows++;
                }
                else
                {
                    output += line + "\n";
                }

                line = BR.readLine();
            }

            BR.close();

            BufferedWriter BW = new BufferedWriter(new FileWriter(tableName + ".db"));
            BW.write(header + "\n");
            BW.write(output);

            BW.close();
        }
        finally
        {
            BR.close();
        }

        return deletedRows;
    }

    public static boolean processLine(String line)
    {
        if (line.startsWith("CREATE TABLE"))
        {
            String name = line.substring("CREATE TABLE ".length());
            name = name.substring(0, name.indexOf(" ")).trim();

            int index1 = line.indexOf("(");
            int index2 = line.indexOf(")");

            String[] columns = line.substring(index1 + 1, index2).split(",");
            for (int i = 0; i < columns.length; i++)
                columns[i] = columns[i].trim();

            try
            {
                createTable(name, columns);
                System.out.println("Table created.");
            }
            catch (IOException e)
            {
                System.out.println("Cannot create table: " + e.getMessage());
            }
        }
        else if (line.startsWith("INSERT INTO"))
        {
            String name = line.substring("INSERT INTO ".length());
            name = name.substring(0, name.indexOf(" ")).trim();

            int index1 = line.indexOf("(");
            int index2 = line.indexOf(")");

            line = line.substring(index1 + 1, index2);
            ArrayList<String> valueList = new ArrayList<String>();

            Pattern P = Pattern.compile("\"([^\"]*)\"");
            Matcher M = P.matcher(line);
            while (M.find())
            {
                valueList.add(M.group(1));
            }

            String[] values = new String[0];
            values = valueList.toArray(values);

            try
            {
                insertInto(name, values);
                System.out.println("Row inserted.");
            }
            catch (IOException e)
            {
                System.out.println("Cannot insert row: " + e.getMessage());
            }
        }
        else if (line.startsWith("DELETE FROM"))
        {
            String name = line.substring("DELETE FROM ".length());
            name = name.substring(0, name.indexOf(" ")).trim();

            int index1 = line.indexOf("WHERE ");

            line = line.substring(index1 + "WHERE ".length());

            Pattern P = Pattern.compile("([^\"]*)=\"([^\"]*)\"");
            Matcher M = P.matcher(line);

            if ( !M.find()) throw new InvalidParameterException();

            String columnName = M.group(1);
            String value = M.group(2);

            try
            {
                int rowsDeleted = deleteFrom(name, columnName, value);
                System.out.println(Integer.toString(rowsDeleted) + " row(s) deleted.");
            }
            catch (IOException e)
            {
                System.out.println("Cannot delete rows: " + e.getMessage());
            }
        }
        else if (line.startsWith("DROP TABLE"))
        {
            String param = line.substring("DROP TABLE ".length());

            try
            {
                dropTable(param);
                System.out.println("Table dropped.");
            }
            catch (IOException e)
            {
                System.out.println("Cannot drop table: " + e.getMessage());
            }
        }
        else if (line.equals("EXIT"))
        {
            System.out.println("Bye.");
            return false;
        }
        else
        {
            System.out.println("Invalid command (use EXIT to quit).");
        }

        return true;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        BufferedReader BR = new BufferedReader(new InputStreamReader(System.in));

        while (true)
        {
            String line = BR.readLine();

            if (line == null)
                return;

            try
            {
                if (! processLine(line))
                {
                    return;
                }
            }
            catch (Exception e)
            {
                System.out.println("Syntax error.");
            }
        }
    }
}
