/*
 * CS255: Programming Project #1
 *
 * ProviderGUI.java 
 */

//package eLecture;

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import java.math.BigInteger;

import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;



public class ProviderGUI implements ActionListener {

    // GUI components
    private JFrame mainFrame;
    private JPanel inputPanel;
    private JPanel buttonPanel;
    private JPanel messagePanel;
    private JLabel contentLabel;
    private JLabel enccontentLabel;
    private JLabel passwdLabel;
    private JLabel encpasswdLabel;
    private JLabel masterpwdLabel;
    private JTextField contentField;
    private JTextField enccontentField;
    private JTextField passwdField;
    private JTextField encpasswdField;
    private JPasswordField masterpwdField;
    private JButton submitButton;
    private JScrollPane messageScrollPane;
    private JTextArea messageArea;
    private final int BLOCK_SIZE = 16;

    //
    // Your variable declarations (if any) can go here:
    //    
    
    public ProviderGUI() {
        InitComponents();
 
        //
        // Your initialization code (if any) can go here:
        //    
    }

    /**
     * Initialize GUI components
     * 
     */
    private void InitComponents() {        
        inputPanel = new JPanel(new GridLayout(3, 4, 10, 5));
        contentLabel = new JLabel("Read plaintext content from");
        contentField = new JTextField("lecture.txt");
        enccontentLabel = new JLabel("Save protected content to");
        enccontentField = new JTextField("lecture.enc");
        passwdLabel = new JLabel("Read plaintext passwords from");
        passwdField = new JTextField("passwd.txt");
        encpasswdLabel = new JLabel("Save protected passwords to");
        encpasswdField = new JTextField("passwd.enc");
        masterpwdLabel = new JLabel("Master password");
        masterpwdField = new JPasswordField();
        buttonPanel = new JPanel();
        messagePanel = new JPanel();
        inputPanel.add(contentLabel);
        inputPanel.add(contentField);
        inputPanel.add(enccontentLabel);
        inputPanel.add(enccontentField);
        inputPanel.add(passwdLabel);
        inputPanel.add(passwdField);
        inputPanel.add(encpasswdLabel);
        inputPanel.add(encpasswdField);
        inputPanel.add(masterpwdLabel);
        inputPanel.add(masterpwdField);
        inputPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
  
        buttonPanel = new JPanel();
        submitButton = new JButton("Submit");
        submitButton.addActionListener(this);
        buttonPanel.add(submitButton);
  
        messagePanel = new JPanel(new BorderLayout());
        messagePanel.setBorder(BorderFactory.createEtchedBorder());
        messageArea = new JTextArea("Hello\n");
        messageArea.setEditable(false);
        messageScrollPane = new JScrollPane(messageArea);
        messagePanel.add(messageScrollPane);
        
        mainFrame = new JFrame("ProviderGUI");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getRootPane().setDefaultButton(submitButton);
        mainFrame.getContentPane().setLayout(new GridLayout(3, 0, 10, 10));
        mainFrame.getContentPane().add(inputPanel);
        mainFrame.getContentPane().add(buttonPanel);
        mainFrame.getContentPane().add(messagePanel);        
        mainFrame.pack();
        mainFrame.setVisible(true);
    }
    private SecretKey genKey(SecureRandom sr, String algorithm){
        KeyGenerator encKeygen = null;
        try{
            encKeygen = KeyGenerator.getInstance(algorithm);
            encKeygen.init(sr);
        }
        catch(NoSuchAlgorithmException ex){
            System.out.println(ex);
        }
        return encKeygen.generateKey();
    }

    /**
    * Handle submit button event.
    * 
    */  
    public void actionPerformed(ActionEvent event) {
        
        // Store values provided by GUI into variables
	String contentfile = contentField.getText(); 
        String enccontentfile = enccontentField.getText();
        String passwdfile = passwdField.getText();
        String encpasswdfile = encpasswdField.getText();
        char[] masterpwd = masterpwdField.getPassword();
        byte[] msg = new byte[1];

        // Read the plaintext content file
        String plaintext = new String();
        try {

	        FileReader fr = new FileReader(contentfile);
            BufferedReader in = new BufferedReader(fr);
            String temp = in.readLine();
            while (temp != null)
            {
                plaintext += temp + "\n";
                temp = in.readLine();
            }
            msg = plaintext.getBytes();

	}
	catch(IOException iox) {
	    System.out.println(iox.getMessage());
	    iox.printStackTrace();
	}
       
        //
        // Most of your code can go here, right now we are just copying the
        // plaintext content to the output file. Your code should generate 
        // and write protected content and the protected password file.
        //

        // our code
	try {
            SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");
            prng.setSeed(masterpwd.toString().getBytes());

            // Generate block cipher key
            SecretKey KBC = genKey(prng, "AES");

            // Generate MAC Key
            SecretKey KMAC = genKey(prng,"AES");

            // Key Material
            SecureRandom K = SecureRandom.getInstance("SHA1PRNG");
            byte[] bytes = new byte[BLOCK_SIZE]; //get the block size
            K.nextBytes(bytes);
            byte[] Kseed = K.generateSeed(BLOCK_SIZE);

            //i don't understand this part very well. it seems K gets overwritten.
            K = SecureRandom.getInstance("SHA1PRNG");
            K.setSeed(Kseed);

            // Generate temp block cipher key
            SecretKey Ktemp = genKey(K, "AES");


            // Generate MAC temp Key
            // this variable never gets used, is there a problem?
            SecretKey KMACtemp = genKey(K, "HmacMD5");

            //CounterMode Encryption

            byte[] cipherTxt = CounterMode.encrypt(Ktemp,true, msg);
            //MAC
            byte[] macContent = MacMessage.doMac(cipherTxt, KMACtemp);
            writeToFile(enccontentfile,cipherTxt,macContent);

            byte[] cipherTxtPasswd = CounterMode.encrypt(KBC,true,Kseed);
            byte[] macPasswd = MacMessage.doMac(cipherTxtPasswd,KMAC);
            writeToFile(encpasswdfile,cipherTxtPasswd,macPasswd);

            FileInputStream fis = new FileInputStream(enccontentfile);
            byte[] cipherTemp = new byte[cipherTxt.length];
            fis.read(cipherTemp);
            fis.close();

            byte[] PT = CounterMode.encrypt(Ktemp,false,cipherTemp);
            FileOutputStream fo = new FileOutputStream("aa.txt");
            fo.write(PT);
            fo.flush();
            fo.close();

        }
        catch(Exception exc){
            System.out.println(exc);
        }

        String status = "Success!\n";
        messageArea.append(status);
        mainFrame.repaint();



    }
    private void writeToFile(String file, byte[] content,byte[] mac){
       try{
           FileOutputStream fos = new FileOutputStream(file);
           fos.write(content);
           fos.write(mac);
           fos.flush();
           fos.close();
       }
        catch(Exception e){
           System.out.println(e);
       }
    }

    /**
     * Create the GUI and show it. 
     */
    private static void createAndShowGUI() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        ProviderGUI provider = new ProviderGUI();
    }

    public static void main(String[] args) {
        Runnable GUI = new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        };
        javax.swing.SwingUtilities.invokeLater(GUI);
    }
}
