package dao;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import error.GExcptSQL;
import gdms.Configuration;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;


public class DBManagement {

    public static String[] userTables = {
            "administrator",
            "student",
            "teacher"
    };
    public static String[] graduationDesignTables = {
        "graduation_design",
        "graduation_design_finished_product",
        "graduation_design_finished_product_mentor_score",
        "graduation_design_finished_product_reviewer_score",
        "graduation_design_information",
        "graduation_design_opening_report",
        "graduation_design_opening_report_opinion_record",
        "graduation_design_reply",
        "graduation_design_reply_opinion_record_score"
    };
    public static String[] studentInfo = {
            "id",
            "password",
            "name",
            "e_mail_location",
            "phone_number",
            "grade",
            "profession_code"
    };
    public static String[] teacherInfo = {
            "id",
            "password",
            "name",
            "e_mail_location",
            "phone_number",
            "job_title",
            "education",
            "profession_code"
    };
    public static String[] administratorInfo = {
            "id",
            "password",
            "name",
            "e_mail_location",
            "phone_number"
    };
    //<table1.x_id,table2.x_status>
    public static String[][] graduationDesignStudentTables ={
            {"graduation_design.student_id","graduation_design.student_choose_teacher_status"},
            {"graduation_design.student_id","graduation_design_information.student_fill_graduation_design_information_status"},
            {"graduation_design.student_id","graduation_design_opening_report.opening_report_status"},
            {"graduation_design_opening_report_view.leader_student_id","graduation_design_opening_report_opinion_record.opening_report_secretary_record_status"},
            {"graduation_design_opening_report_view.student1_id","graduation_design_opening_report_opinion_record.opening_report_secretary_record_status"},
            {"graduation_design_opening_report_view.student2_id","graduation_design_opening_report_opinion_record.opening_report_secretary_record_status"},
            {"graduation_design.student_id","graduation_design_finished_product.finished_product_status"},
            {"graduation_design_reply_view.leader_student_id","graduation_design_reply_opinion_record_score.reply_secretary_record_status"},
            {"graduation_design_reply_view.teacher1_id","graduation_design_reply_opinion_record_score.reply_secretary_record_status"},
            {"graduation_design_reply_view.teacher2_id","graduation_design_reply_opinion_record_score.reply_secretary_record_status"}
    };
    public static String[][] graduationDesignTeacherTables = {
            {"graduation_design.teacher_id","graduation_design.teacher_choose_student_status"},
            {"graduation_design.teacher_id","graduation_design_opening_report_opinion_record.opening_report_mentor_opinion_status"},
            {"graduation_design_opening_report_view.leader_teacher_id","graduation_design_opening_report_opinion_record.opening_report_teacher_team_opinion_status"},
            {"graduation_design_opening_report_view.teacher1_id","graduation_design_opening_report_opinion_record.opening_report_teacher_team_opinion_status"},
            {"graduation_design_opening_report_view.teacher2_id","graduation_design_opening_report_opinion_record.opening_report_teacher_team_opinion_status"},
            {"graduation_design_opening_report_opinion_record.opening_report_college_teacher_id","graduation_design_opening_report_opinion_record.opening_report_college_opinion_status"},
            {"graduation_design.teacher_id","graduation_design_finished_product_mentor_score.finished_product_mentor_score_status"},
            {"graduation_design_finished_product_reviewer_score.reviewer_teacher_id","graduation_design_finished_product_reviewer_score.finished_product_reviewer_score_status"},
            {"graduation_design_reply_view.leader_teacher_id","graduation_design_reply_opinion_record_score.reply_teacher_team_score_status"},
            {"graduation_design_reply_view.teacher1_id","graduation_design_reply_opinion_record_score.reply_teacher_team_score_status"},
            {"graduation_design_reply_view.teacher2_id","graduation_design_reply_opinion_record_score.reply_teacher_team_score_status"},
            {"graduation_design_reply_opinion_record_score.reply_college_teacher_id","graduation_design_reply_opinion_record_score.reply_college_score_status"},
            {"graduation_design_reply_opinion_record_score.reply_school_teacher_id","graduation_design_reply_opinion_record_score.reply_school_score_status"}
    };
    public static String[][] allStatus = {
            {"graduation_design","teacher_choose_student_status"},
            {"graduation_design","student_choose_teacher_status"},
            {"graduation_design_information","student_fill_graduation_design_information_status"},
            {"graduation_design_opening_report","opening_report_status"},
            {"graduation_design_opening_report_opinion_record","opening_report_mentor_opinion_status"},
            {"graduation_design_opening_report_opinion_record","opening_report_teacher_team_opinion_status"},
            {"graduation_design_opening_report_opinion_record","opening_report_college_opinion_status"},
            {"graduation_design_opening_report_opinion_record","opening_report_secretary_record_status"},
            {"graduation_design_finished_product","finished_product_status"},
            {"graduation_design_finished_product_mentor_score","finished_product_mentor_score_status"},
            {"graduation_design_finished_product_reviewer_score","finished_product_reviewer_score_status"},
            {"graduation_design_reply_opinion_record_score","reply_secretary_record_status"},
            {"graduation_design_reply_opinion_record_score","reply_teacher_team_score_status"},
            {"graduation_design_reply_opinion_record_score","reply_college_score_status"},
            {"graduation_design_reply_opinion_record_score","reply_school_score_status"}
    };
    public static String driverClassName="org.mariadb.jdbc.Driver";



    public static DataSource dataSource = new DataSource();

    private static boolean ifInit = false;

    public static void init(){
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setUrl(Configuration.dbUrl);
        poolProperties.setDriverClassName(DBManagement.driverClassName);
        poolProperties.setUsername(Configuration.dbUsername);
        poolProperties.setPassword(Configuration.dbPassword);
        dataSource.setPoolProperties(poolProperties);
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        ifInit = true;
    }
    public static Connection getConnection(){
        if(!ifInit) return null;
        try {
            return DriverManager.getConnection(Configuration.dbUrl,Configuration.dbUsername,Configuration.dbPassword);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String[][] getUserStatusTables(String userType){
        if(userType.equals("student")){
            return graduationDesignStudentTables;
        }
        if(userType.equals("teacher")){
            return graduationDesignTeacherTables;
        }
        return null;
    }
    public static String[] getUserInfoTables(String userType){
        if(userType.equals("administrator")){
            return administratorInfo;
        }
        if(userType.equals("student")){
            return studentInfo;
        }
        if(userType.equals("teacher")){
            return teacherInfo;
        }
        return null;
    }
    public static void delete(String table, Map<String,String> limits) throws GExcptSQL {
        Delete delete = new Delete(table, limits);
        String sql = delete.getSQL();
        update(sql);
    }
    public static void insert(String table, Map<String, String> vMap) throws GExcptSQL {
        Insert insert = new Insert(table, vMap);
        String sql = insert.getSQL();
        update(sql);
    }
    public static List<String[]> select(List<String> columns, String table, Map<String,String> limits, int startRow, int endRow) throws Exception {
        Select select = new Select(columns,table,limits,startRow,endRow);
        String sql = select.getSQL();
        return query(sql);
    }
    public static void update(String table, Map<String,String> vMap, Map<String,String> limits) throws GExcptSQL {
        Update update = new Update(table,vMap,limits);
        String sql = update.getSQL();
        update(sql);
    }
    public static void updateAll(String table, List<String> fields, String increment) throws GExcptSQL {
        UpdateAll updateAll = new UpdateAll(table,fields,increment);
        String sql = updateAll.getSQL();
        update(sql);
    }
    public static List<String[]> query(String sql) throws Exception {
        if(!ifInit) return null;
        List<String[]> ls;
        Connection con = null;
        try{
            con = DBManagement.getConnection();
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            ResultSetMetaData rsm = rs.getMetaData() ;
            int columnCount = rsm.getColumnCount();
            ls = new ArrayList<>();
            while(rs.next()){
                String[] s = new String[columnCount];
                for(int i=0;i<columnCount;i++){
                    s[i] = rs.getString(i+1);
                }
                ls.add(s);
            }
        } catch (SQLException e) {
            throw new GExcptSQL("Connect Failure\n"+sql);
        }finally {
            if(con!=null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    throw new GExcptSQL("Connection Close Failure");
                }
            }
        }
        return ls;
    }
    public static void update(String sql) throws GExcptSQL {
        if(!ifInit) return;
        Connection con = null;
        try{
            con = DBManagement.getConnection();
            Statement stmt = con.createStatement();
            stmt.executeUpdate(sql);
        } catch (SQLException e) {
            throw new GExcptSQL("Connect Failure\n"+sql);
        }finally {
            if(con!=null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    throw new GExcptSQL("Connection Close Failure");
            }
            }
        }
    }


}
