package javabog;

import java.sql.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.*;
/**
 * Denne javabønne har ansvaret for registrering og logintjek af en bruger.
 * Husk at mail.jar, activation.jar og MySQL-driveren skal være i CLASSPATH.
 */
public class Login
{
	private String brugernavn = "";
	private String adgangskode = "";
	private String epost = "";
	private String meddelelse = "";       // fejlmeddelelse til brugeren

	private boolean tjek = false;         // om adgangskode skal tjekkes
	private boolean loggetInd = false;    // om adgangskoden var korrekt

	public void setBrugernavn(String bn)  { tjek=true; brugernavn=bn; }
	public String getBrugernavn()         { return brugernavn; }

	public void setAdgangskode(String ak) { tjek=true; adgangskode = ak; }

	public void setEpost(String epost)    { this.epost = epost; }
	public String getEpost()              { return epost; }

	public void setMeddelelse(String m)   { meddelelse = m; }
	public String getMeddelelse() { String m=meddelelse; meddelelse=""; return m; }

	/** Egenskaben loggetInd. Kan af sikkerhedsgrunde kun aflæses */
	public boolean isLoggetInd() {
		if (tjek) return false;       // er der sket ændringer skal der logges ind
		return loggetInd;
	}

	/** Forbindelsen til databasen. Oprettes når klassen indlæses */
	private static Connection con = null;
	private static String postserver = null;
	private static String postafsender = null;

	/** Initialisering. Skal kaldes før bønnen bruges */
	public synchronized static void init(ServletContext application)
	{
		if (con!=null) return; // initialisér kun hvis det ikke allerede er gjort

	 	// Opret forbindelse til databasen når klassen bruges første gang
		try {
			String drv=null, url=null, bru=null, adg=null;
			if (application!=null) {
				drv = application.getInitParameter("dbDriver");
				url = application.getInitParameter("dbUrl");
				bru = application.getInitParameter("dbBruger");
				adg = application.getInitParameter("dbAdgangskode");
				postserver = application.getInitParameter("postserver");
				postafsender = application.getInitParameter("postafsender");
			}
			if (drv==null) drv = "com.mysql.jdbc.Driver";
			if (url==null) url = "jdbc:mysql:///test";
			if (bru==null) bru = "root";
			if (adg==null) adg = "";

			Class.forName(drv);                                  // indlæs driver
			con = DriverManager.getConnection(url, bru, adg);    // opret forbindelse

			Statement s = con.createStatement();

			try { // opret tabellen (dette giver en fejl hvis den allerede eksisterer)
				s.executeUpdate("CREATE TABLE brugere (brugernavn varchar(20), "+
												"adgangskode varchar(20), epost varchar(50))");

				// Indsæt så også nogle brugere, så der er nogle til at starte med
				s.executeUpdate("INSERT INTO brugere VALUES ('Jacob','hemli','')");
				s.executeUpdate("INSERT INTO brugere VALUES ('Preben','hemli','')");
				s.executeUpdate("INSERT INTO brugere VALUES ('Søren','hemli','')");
				System.out.println("Bemærk: Standardbrugere oprettet (sikkerhedshul!)");
			} catch (SQLException sqlex) {} // OK med fejl her, log dem derfor ikke

			ResultSet rs = s.executeQuery("SELECT brugernavn FROM brugere");
			while (rs.next()) System.out.println( "bruger: "+rs.getString(1) );
			rs.close();
			s.close();
		}
		catch (Exception ex) {
			System.out.println("Problem med databasen: "+ex);
			ex.printStackTrace(); // Kritisk fejl, log den
			con = null; // sæt forbindelsen til null og prøv at oprette den senere
		}
	}

	/** Tjekker om brugernavn og adgangskode er OK */
	public void tjekLogin()
	{
		if (!tjek) return; // er der ikke sket ændringer behøver vi ikke tjekke igen
		loggetInd = false;
		tjek = false;
		if (brugernavn.length() > 0 && adgangskode.length() > 0) try {
			if (con == null) init(null); // ingen forbindelse - forsøg at oprette en
			PreparedStatement s = con.prepareStatement(
				"SELECT brugernavn FROM brugere WHERE brugernavn=? AND adgangskode=?");
			s.setString(1, brugernavn);
			s.setString(2, adgangskode);
			ResultSet rs = s.executeQuery();
			if (rs.next()) loggetInd = true; // korrekt! Brugeren er logget ind.
			else meddelelse = "Forkert brugernavn eller adgangskode";

			rs.close();
			s.close();
		} catch (Exception e) {
			e.printStackTrace();
			meddelelse = "Kunne ikke logge ind: " + e;
		}
	}

	/**
	 * Registrerer ny bruger og sender adgangskode til epost-adressen
	 * @return true hvis oprettelsen gik godt, ellers false.
	 */
	public boolean opretBruger()
	{
		tjek = false;
		loggetInd = false;
		if (brugernavn.length() >= 1 && epost.length() >= 5 ) try {
			String nyAdgangskode = lavNyAdgangskode();
			PreparedStatement s = con.prepareStatement(
				"INSERT INTO brugere VALUES (?,?,?)");
			s.setString(1, brugernavn);
			s.setString(2, nyAdgangskode);
			s.setString(3, epost);
			s.executeUpdate();
			s.close();
			sendAdgangskode(nyAdgangskode);
			return true;             // oprettelse lykkedes!
		} catch (Exception e) {
			e.printStackTrace();
			meddelelse = "Fejl under oprettelsen: "+e;
		} else {
			meddelelse = "Brugernavn og epost skal være udfyldt";
		}
		return false;
	}

	/**
	 * adgangskode genereres til ny bruger
	 * @return koden
	 */
	private String lavNyAdgangskode()
	{
		String ord = "";
		for (int j=0; j<6; j++) {
			ord = ord + (char) ('a' + (char) (Math.random()*25));
		}
		return ord;
	}

	/**
	 * Send adgangskoden til brugeren med e-post
	 */
	private void sendAdgangskode(String adgangskoden) throws Exception 
	{
		if (postafsender==null) postafsender = "din@adresse.dk";
		if (postserver==null) postserver = "post.tele.dk";

		Properties prop = new Properties();
		prop.setProperty("mail.host", postserver);   // afhænger af internetudbyder
		prop.setProperty("mail.transport.protocol", "smtp");
		Session session = Session.getInstance(prop);

		// Opbyg beskedden
		Message besked = new MimeMessage(session);
		besked.setFrom(new InternetAddress(postafsender));
		besked.setRecipient(Message.RecipientType.TO, new InternetAddress(epost));
		besked.setSubject("Din adgangskode til javabog.dk");
		String txt = "Din adgangskode til javabog.dk er: "+adgangskoden+"\n"
			+ "Du kan også logge ind ved at klikke på nedenstående henvisning:\n"
			+ "http://javabog.dk:8080/JSP/kode/kapitel_09/log_ind.jsp?brugernavn="
			+ java.net.URLEncoder.encode(brugernavn,"UTF-8")+"&adgangskode="
			+ java.net.URLEncoder.encode(adgangskoden,"UTF-8")+"&handling=log+ind";
		besked.setContent(txt, "text/plain"); // put beskedden ind
		System.out.println(txt);              // skriv også beskedden i serverens log

		Transport.send(besked);               // send beskedden
		meddelelse = "Adgangskoden er sendt til adressen "+ epost;
	}
}