package xdc.services.global;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.mozilla.javascript.WrappedException;

import xdc.services.spec.Atom;
import xdc.services.spec.Pkg;
import xdc.services.spec.SessionRuntimeException;

public class Digest {

    static final public String FILENAME = "package/.md5sums";
    
    Map<String,String> cursums = new HashMap<String,String>();
    Map<String,String> oldsums = new HashMap<String,String>();
    
    Set<String> bodyChanges = new HashSet<String>();
    boolean specChanged = false;
    Pkg pkg;
    
    Clock clock = new Clock();

    public Digest( Pkg pkg )
    {
        this.pkg = pkg;
    }
    
    public void update()
    {
        clock.enable();
        clock.reset();
        
        File file = new File(pkg.getBaseDir() + "/" + FILENAME);
        
        loadCookie(file);  
        
        String md5 = encodeBytes(getBytes(pkg.getBaseDir() + "/package.xdc"));
        cursums.put("package", md5);
        if (!md5.equals(oldsums.get("package"))) {
            specChanged = true;
        }
        
        for (Atom uname : pkg.getInterNames()) {
            checkUnit(uname.getText());
        }

        for (Atom uname : pkg.getModNames()) {
            checkUnit(uname.getText());
        }
        
        if (specChanged) {
            pkg.setSpecChanged();
            saveCookie(file);
        }
        else if (bodyChanges.size() > 0) {
            pkg.setBodyChanges(bodyChanges);
            saveCookie(file);
        }
        
        clock.print("MD5 " + specChanged + ' ' + bodyChanges);
    }
    
    private byte[] getBytes( String fname )
    {
        byte[] res = null;

        try {
            File file = new File(fname);
            FileInputStream stream = new FileInputStream(file);
            res = new byte[(int) file.length()];
            stream.read(res);
            stream.close();
        }
        catch (Exception e) {
            Err.exit(e);
        }
        
        return res;
    }
    
    private void checkUnit( String uname )
    {
        String fname = pkg.getBaseDir() + '/' + uname + ".xdc";
        byte[] bytes = getBytes(fname);
        String md5 = encodeBytes(bytes);
        cursums.put(uname, md5);

        if (md5.equals(oldsums.get(uname))) {
            cursums.put(uname + "-spec", oldsums.get(uname + "-spec"));
            return;
        }

        String text = new String(bytes);
        int k = text.indexOf("\nimplementation");
        
        if (k == -1) {
            specChanged = true;
            cursums.put(uname + "-spec", oldsums.get(uname + "-spec"));
            return;
        }
        
        md5 = encodeBytes(bytes, k);
        cursums.put(uname + "-spec", md5);
        if (md5.equals(oldsums.get(uname + "-spec"))) {
            bodyChanges.add(uname);
        }
        else {
            specChanged = true;
        }
    }
    
    private String encodeBytes( byte[] bytes )
    {
        return encodeBytes(bytes, bytes.length);
    }
    
    private String encodeBytes( byte[] bytes, int count )
    {
        MessageDigest algorithm;
        try {
            algorithm = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            return null;
        } 
        StringBuffer hexString = new StringBuffer(); 

        algorithm.reset();
        algorithm.update(bytes, 0, count);
        byte[] digest = algorithm.digest();
        for (int i = 0; i < digest.length; i++) { 
            int d = 0xFF & digest[i];
            String tmp = Integer.toHexString(d);
            if (d <= 0xF) {
                hexString.append("0");
            }
            hexString.append(tmp);
        }

        return (hexString.toString());
    }
    
    @SuppressWarnings("unchecked")
    private void loadCookie( File file )
    {
        if (!file.exists()) {
            return;
        }
        
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
            oldsums = (HashMap<String,String>)ois.readObject();
        }
        catch (Exception e) {
            ;
        }
    }
    
    private void saveCookie( File file )
    {
        ObjectOutputStream oos = null;
        
        try {
            file.delete();
            oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
            oos.writeObject(cursums);
        }
        catch (Exception e) {
            e.printStackTrace();
            SessionRuntimeException se =
                new SessionRuntimeException(e.getMessage());
            throw (se);
        }
        finally {
            if (oos != null) {
                try {
                    oos.close();
                }
                catch (java.io.IOException e) {
                    ;
                }
            }
        }
    }
}
