/*
* Simple Database Implementation
*/

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * @author anwar
 */
public class DbaseImpl implements DBase {
    private Bag<Student> bag;
    private boolean databaseOpenFlag = false;
    String dbName;
    DbaseImpl()
    {
        bag = new SortedBag();
    }
    @Override
    public boolean open(String dbName) {
        this.dbName = dbName;
        JSONParser parser = new JSONParser();
	try {
		Object obj = parser.parse(new FileReader(dbName));
		//JSONObject jsonObject = (JSONObject) obj;
                JSONArray students = (JSONArray)obj;
                Iterator<JSONObject> iterator = students.iterator();
                while (iterator.hasNext()) {
                    //JSONObject jsonObject = (JSONObject) iterator.next();
                    JSONObject jsonObject = iterator.next();
                    String ID = (String) jsonObject.get("id");
                    String firstName= (String)jsonObject.get("firstname");
                    String lastName= (String)jsonObject.get("lastname");
                    bag.insert(new Student(ID,firstName,lastName, "1/1/2014"));
		}
	} catch (FileNotFoundException e) {
		//e.printStackTrace();
                System.out.println("Database file not found:" + dbName);
                return false;
	} catch (IOException e) {
		//e.printStackTrace();
                System.out.println("File I/O error.");
                return false;
	} catch (ParseException e) {
		//e.printStackTrace();
                System.out.println("JSON parse error.");
                return false;
	}
        databaseOpenFlag = true;
        return true;
    }

    @Override
    public boolean close() 
    {
        if(!databaseOpenFlag) {return false;}
        try {
            FileWriter file = new FileWriter(dbName);
            JSONArray list = new JSONArray();
            for(Student s: bag){
                JSONObject obj = new JSONObject();
                obj.put("id", s.getID());
                obj.put("firstname", s.getFirstName());
                obj.put("lastname", s.getLastName());
                list.add(obj);     
            }
            file.write(list.toJSONString());
            file.write("\n");
            
            file.flush();
            file.close();
			bag.clear();	//delete everything from bag
        } catch (IOException e) {
		//e.printStackTrace();
                System.out.println("File I/O error.");
        }
        databaseOpenFlag = false;
        return true;
    }

    @Override
    public Student get(String id) {
        //TO DO
        return null;
    }
    
    @Override
    public boolean insert(Student s) {
       //TO DO
        return true;
    }
    /**
     *remove a student from databse
     *@param ID student id
     *return true if student can be deleted. false if student cannot be deleted or does not exists;
     */       
    @Override
    public boolean remove(String ID) {
        //TO DO
		return true;
    }

    @Override
    public boolean create(String dbName) {
        File file = new File(dbName);
        if(!file.exists()) {
            try {
                FileWriter temp = new FileWriter(dbName);
                temp.write("[{\"id\":\"1\",\"firstname\":\"admin\",\"lastname\":\"admin\",\"dob\":\"01/01/2014\"}]\n");
                temp.flush();
                temp.close();
                return true;
                
            } catch (IOException ex) {
                System.out.println("Cannot create database file:" + dbName);
                return false;
            }
        } 
        return false;
    }

    @Override
    public Iterator<Student> iterator() {
        return bag.iterator();
    }

    @Override
    public Bag<Student> find(String name) {
        System.out.println("TO be implemented.");
        Bag<Student> temp = new SortedBag();
        // TO DO
        return temp;
    }

    @Override
    public boolean isOpen() {
        return databaseOpenFlag;
    }
}
