import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.util.Date.*;
import java.lang.*;
import java.lang.Object.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

  public class server  extends UnicastRemoteObject  implements simple {
       String[] voters=new String[1000];
       int[] voters_vote = new int[1000];
       String[] candidates=new String[10];
       String[] idea=new String[10];
       int[] kommata=new int[10];
       int[] candidates_votes=new int[10];
       int candidates_num=0,voters_num=0,POS,total_votes=0,kommata_num=0;

	  private int compare(String tr,String te) {
           int i=0,n1,n2,j;
                 if(tr==null || te==null) return 0;
                 n1=tr.length();
                 n2=te.length();
                 if(n1!=n2) return 0;
                 for(j=0;j<n1;j++)
                         if(tr.charAt(j)!=te.charAt(j)) break;
                 if(j==n1) return 1;
                 return 0;
         }

        public void add_kommata(String komma) {
            int i;
            for(i=0;i<kommata_num;i++)
               if(compare(komma,idea[i])==1) return;
            idea[kommata_num]=komma;
            kommata[kommata_num]=0;
            kommata_num++;
        }

        public void kommata_votes(String komma) {
             int i;
             for(i=0;i<kommata_num;i++)
               if(compare(komma,idea[i])==1) {
                  kommata[i]++;
                  return;
               }
               return;
        }

        public void write_logfiles(String person,String logfile) {
          FileReader  tmp2 =null;
          BufferedReader tmp2_buff =null;
          File tmp_voters = null;
          FileWriter writer_voters = null;

          File tmp = null;
          FileWriter tmp_writer = null;
          FileReader voters_log  = null;
          BufferedReader voters_buff = null;

          boolean eof = false;
          try {
          	tmp = new File("tmp");
          	tmp_writer = new FileWriter(tmp);
          	voters_log  = new FileReader(logfile);
          	voters_buff = new BufferedReader(voters_log);

          	eof = false;
          	while(!eof) {
                   String line = voters_buff.readLine();
                   if(line==null) eof = true;
                   else {
                      tmp_writer.write(line);
                      tmp_writer.write("\n");
                   }
          	}
          	tmp_writer.close();
                voters_buff.close();
          } catch (Exception e1) {
              System.out.println(e1.toString());
          }

          try {
          	 tmp2 = new FileReader("tmp");
          	 tmp2_buff = new BufferedReader(tmp2);
          	 tmp_voters = new File(logfile);
          	 writer_voters = new FileWriter(tmp_voters);
          } catch (Exception e2) {
              System.out.println(e2.toString());
          }


          try {
            writer_voters.write(person);
            writer_voters.write("\n");
            eof = false;
            while(!eof) {
                String line = tmp2_buff.readLine();
                 if(line==null) eof = true;
                  else {
                      writer_voters.write(line);
                      writer_voters.write("\n");
                  }
            }
            writer_voters.write("\n");
            writer_voters.close();
            tmp2_buff.close();
          }catch (IOException e) {
             System.out.println("Cannot to file log  " + e.toString());
          }
        }


        public void restorelogfiles() {
          FileReader tmp1=null,tmp2 = null;
          BufferedReader voters_logs=null,candidates_logs = null;
          int i;
           System.out.println("Candidates " + candidates_num);
           try {
               tmp1  = new FileReader("voters_log");
               voters_logs = new BufferedReader(tmp1);
               boolean eof = false;
               while(!eof) {
                   String line = voters_logs.readLine();
                   if(line==null) eof = true;
                   else {
                     for(i=0;i<voters_num;i++)
                        if(compare(voters[i],line)==1) {
                              voters_vote[i]=1;
                        }
                   }
               }
               voters_logs.close();
           } catch (Exception e) {
              System.out.println("");
           }

           try {
               tmp2 = new FileReader("candidates_log");
               candidates_logs = new BufferedReader(tmp2);
               boolean eof = false;
               while(!eof) {
                   String line = candidates_logs.readLine();
                   if(line==null) eof = true;
                   else {
                     for(i=0;i<candidates_num;i++)
                        if(compare(candidates[i],line)==1) {
                          candidates_votes[i]=candidates_votes[i]+1;
                          total_votes=total_votes+1;
                          //kommata_votes(idea[i]);
                          break;
                        }
                        if(i==candidates_num && compare("akyro",line)==1) {
                          candidates_votes[i]=candidates_votes[i]+1;
                          total_votes=total_votes+1;
                        }

                   }
               }
               candidates_logs.close();
           } catch (Exception e) {
              System.out.println("");
           }
            return ;
  }



	public void find_voters() {
  	   boolean eof = false;
     	    try {
        	  FileReader gr = new FileReader("voters.dat");
	          BufferedReader buff = new BufferedReader(gr) ;
        	  while(!eof) {
           	        String line = buff.readLine();
             		if(line==null) eof = true;
                        else {
                          voters[voters_num]=line;
                          voters_vote[voters_num]=0;
                          voters_num++;
                        }
          	  }
                  voters_num--;
          	  buff.close();
     	     } catch (Exception e2) {
                System.out.println(e2);
            }
         }


         public void find_candidates() {
           boolean eof = false;
            try {
                  FileReader gr = new FileReader("candidates.dat");
                  BufferedReader buff = new BufferedReader(gr) ;
                  while(!eof) {
                        String line = buff.readLine();
                        String line2 = buff.readLine();
                        if(line==null) eof = true;
                        else {
                           candidates[candidates_num]=line;
                           candidates_votes[candidates_num]=0;
                           add_kommata(line2);
                           idea[candidates_num]=line2;
                           candidates_num++;
                        }
                  }
                  candidates[candidates_num]="leuko";
                  idea[candidates_num]=" ";
                  candidates_votes[candidates_num]=0;
                  candidates_num++;
                  candidates[candidates_num]="akyro";
                  candidates_votes[candidates_num]=0;
                  idea[candidates_num]=" ";
                  candidates_num++;
                  buff.close();
             } catch (Exception e2) {
                System.out.println(e2);
            }


         }


         public int can_vote(String voter_name) {
            int i,tmp;

            for(i=0;i<voters_num;i++) {
                tmp=compare(voters[i],voter_name);
                POS=i;
                if(tmp==1) return(1-voters_vote[i]);
            }
            return -1;
         }



         public String list_candidates()  throws RemoteException {
            String result="\n";
            int i;

             for(i=0;i<candidates_num-1;i++)
              result=result + candidates[i] + "   " + idea[i] +"\n";
            return(result);
         }



         public String vote(String voter_name,String candidate_name)  throws RemoteException {
           int i,valid_vote;
              System.out.println("Request received from voter " + voter_name);

              valid_vote=can_vote(voter_name);
              if(valid_vote==0)  {
                     System.out.println("Request Failed: Voter " + voter_name + " has already vote");
                     return("Sorry but you can vote only once.");
               }

              if(valid_vote==-1)  {
                  System.out.println("Request Failed: Voter " + voter_name + " has not the right to vote.");
                     return("Sorry you don't have the right to vote");
              }


              for(i=0;i<candidates_num;i++)
                  if(compare(candidate_name,candidates[i])==1) break;

              candidates_votes[i]=candidates_votes[i]+1;
              voters_vote[POS]=1;
              total_votes=total_votes+1;
              System.out.println("Request Succeed: Voter " + voter_name + " voted");
              if(i==candidates_num) write_logfiles("akyro","candidates_log");
              else  write_logfiles(candidates[i],"candidates_log");
              write_logfiles(voter_name,"voters_log");
              return("OK");
           }





           public String results(String candidate)  {
             String result="\n";
             int i;

             if(compare(candidate,"all")!=1) {
                for(i=0;i<candidates_num;i++) {
                   if(compare(candidates[i],candidate)==1)
                          result=result +  candidate + "  " + String.valueOf(candidates_votes[i]) + "   " + String.valueOf(candidates_votes[i]*100.0/total_votes) +"%" ;
                }
                if(i==candidates_num) return("Candidate not found");

               return(result);
             }
             else {
               for(i=0;i<candidates_num;i++)
                   result=result + candidates[i] + "  " + String.valueOf(candidates_votes[i]) + "   " +String.valueOf(candidates_votes[i]*100.0/total_votes) + " %"+ "\n";

             }
             return(result);
           }


           public server() throws RemoteException {
               super();
           }


           public static void main(String args[])
           {
              server echo=null;
               // Create and install the security manager
               System.setSecurityManager(new RMISecurityManager());
               try {
                   echo = new server();
                   String url = "//" + args[0] + "/~stefanos/rmi/simple";
                   echo.find_voters();
                   echo.find_candidates();
                   echo.restorelogfiles();
                   // bind the url to echo
                   Naming.rebind(url, echo);
                   System.out.println("Server ready.");

               } catch (Exception e) {
                   System.out.println("server.main: an exception occurred: " +
                                      e.getMessage() + "  " + args[0]);
                   e.printStackTrace();
               }
           }
}
