package manager;

import java.sql.SQLException;
import java.util.Date;
import java.sql.*;

/**
 * Description d'un étudiant de la base.
 * 
 * @author Busca
 *  
 */
class Student {
    int sid;
    String sname;
    String sfname;
    Date birthd;
    float weight;
    int syear;
}


/**
 * Gestionnaire de la base de données Ecole (cf TP1).
 * <p>
 * Avant de remettre ce programme, vérifier qu'il fonctionne sur les machines
 * Linus et le SGBD Oracle de l'EFREI.
 * <p>
 * <b>Note: NE PAS modifier les interfaces définies.</b>
 * 
 * @author Busca
 * 
 */
public class SchoolManager {

    private static Connection conn;
    /**
     * Crée un nouvel objet SchoolManager et effectue une connexion à la base de
     * données spécifiée.
     * 
     * @param url
     *            url de la base de données
     * @param user
     *            nom d'utilisateur
     * @param password
     *            password
     */
    public SchoolManager(String url, String user, String password) throws SQLException {    
		System.out.println("\n---------- Connexion à la base de donnée ----------");
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("-> Driver O.K.");

			conn = DriverManager.getConnection(url, user, password);
			System.out.println("-> Connexion effective !");        

		} catch (Exception e) {
			e.printStackTrace();
		}     
    }

    /**
     * Ferme la connection à la base de données.
     * 
     */
    public void close() throws SQLException {
		System.out.println("\n---------- Fermeture de la connexion ----------");
		conn.close();
		System.out.println("-> Connexion terminée");
    }

    /**
     * Crée un nouvel étudiant dans la base.
     * 
     */
    public boolean createStudent(int sid, String sname, String sfname, Date birthd, float weight, int syear) throws SQLException {
		System.out.println("\n---------- Création d'un étudiant ----------");
		Statement state = conn.createStatement();
		ResultSet result = state.executeQuery("SELECT sid FROM students WHERE sid = " + sid);	
		
		if(result.next()) {
			System.out.println("-> Erreur : un élève existe déjà avec ce sid");
			return false;
		}

		String sql = "INSERT INTO students VALUES(" + sid + ", '" + sname + "', '" + sfname + "', DATE '" + new java.sql.Date(birthd.getTime()) + "', " + weight + ", " + syear + ")";
		state.executeQuery(sql);

		System.out.println("-> L'étudiant a été crée");
		retrieveStudent(sid);
		state.close();
		return true;
    }

    /**
     * Récupère les attributs d'un étudiant existant dans la base.
     * 
     */
    public Student retrieveStudent(int sid) throws SQLException {
		Statement state = conn.createStatement();
		ResultSet result = state.executeQuery("SELECT * FROM students WHERE sid = " + sid);	
		result.next();

		Student s = new Student();
		s.sid = sid;
		s.sname = result.getString("sname");
		s.sfname = result.getString("sfname");
		s.birthd = result.getDate("birthd");
		s.weight = result.getFloat("weight");
		s.syear = result.getInt("syear");

		System.out.println("Affichage de l'étudiant : ");
		System.out.println("Sid : " + s.sid + " | Nom : " + s.sname + " | Prenom : " + s.sfname + " |  Birthday : " + s.birthd + " |  Weight : " + s.weight + " | Syear : " + s.syear);
		
		result.close();
		state.close();
		
		return s;
    }

    /**
     * Met à jour un étudiant existant dans la base. Si un attribut ne doit pas
     * être mis à jour, le paramètre correspondant est null ou négatif. Le
     * paramètre sid est toujours renseigné.
     * 
     */
    public boolean updateStudent(int sid, String sname, String sfname, Date birthd, float weight, int syear) throws SQLException {
		System.out.println("\n---------- Mise à jour d'un étudiant ----------");
		Statement state = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
		ResultSet result = state.executeQuery("SELECT sid FROM students WHERE sid = " + sid);	
		
		if(!result.next()) {
			System.out.println("-> Erreur : Cet élève n'a pas été trouvé");
			return false;
		}

		String sql = "UPDATE students SET sid = " + sid;
		
		if(sname != null)
			sql += ", sname = '" + sname + "'";
		if(sfname != null)
			sql += ", sfname = '" + sfname + "'";
		if(birthd != null)
			sql += ", birthd = date '" + new java.sql.Date(birthd.getTime()) + "'";
		if(weight > 0)
			sql += ", weight = " + weight;
		if(syear > 0)
			sql += ", syear = " + syear;

		sql += " WHERE sid = " + sid;
		state.executeQuery(sql);

		System.out.println("-> L'étudiant (sid = " + sid + ") a bien été mis à jour");
		retrieveStudent(sid);
		state.close();
		return true;
    }

    /**
     * Supprime un étudiant existant dans la base.
     * 
     */
    public boolean deleteStudent(int sid) throws SQLException {
		System.out.println("\n---------- Suppression d'un étudiant ----------");
		Statement state = conn.createStatement();
		ResultSet result = state.executeQuery("SELECT sid FROM students WHERE sid = " + sid);	
		
		if(!result.next()) {
			System.out.println("-> Erreur : Cet élève n'a pas été trouvé");
			return false;
		}

		state.executeQuery("DELETE FROM students WHERE sid = " + sid);
		System.out.println("-> L'élève a bien été supprimé");
		state.close();
		return true;
    }

    /**
     * Programme de test.
     * 
     * @param args
     *            paramètres d'appel
     */
    public static void main(String[] args) throws Exception {
		SchoolManager test = new SchoolManager("jdbc:oracle:thin:@oracle.efrei.fr:1521:sgbd", "lepot", "lepot");

		test.retrieveStudent(6);
		test.updateStudent(6, "Marcel", "Jean", new Date(), 90, 2);

		test.createStudent(100, "La pointe", "Bobby", new Date(), 22f, 1);
		test.updateStudent(100, null, "Check", null, -1, -1);
		test.deleteStudent(100);

		test.close();
    }

}
