package org.apache.savan.atom;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXBuilder;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.util.StAXUtils;
import org.apache.axis2.context.MessageContext;
import org.apache.savan.SavanException;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.sql.*;
import java.util.Date;
import java.util.Properties;

/**
 * This class interface between Derby and Savan atom implementation
 *
 * @author Srinath Perera(hemapani@apache.org)
 */
public class AtomDataSource {
    public static final String SQL_CREATE_FEEDS = "CREATE TABLE FEEDS(id CHAR(250) NOT NULL, " +
                                                  "title CHAR(250), updated TIMESTAMP, author CHAR(250), PRIMARY KEY(id))";
    public static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE ENTIES(feed CHAR(250), content VARCHAR(2000))";

    public static final String SQL_ADD_FEED =
            "INSERT INTO FEEDS(id,title, updated,author) VALUES(?,?,?,?)";
    public static final String SQL_ADD_ENTRY = "INSERT INTO ENTIES(feed, content) VALUES(?,?)";
    public static final String SQL_GET_ENTRIES_4_FEED = "SELECT content from ENTIES WHERE feed=?";
    public static final String SQL_GET_FEED_DATA =
            "SELECT id,title,updated,author from FEEDS WHERE id=?";


    public String framework = "embedded";
    public String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    public String protocol = "jdbc:derby:";
    private Properties props;

    public AtomDataSource() throws SavanException {
        try {
            Class.forName(driver).newInstance();
            System.out.println("Loaded the appropriate driver.");

            props = new Properties();
            props.put("user", "user1");
            props.put("password", "user1");

            Connection connection = getConnection();
            Statement statement = connection.createStatement();

            ResultSet feedtable = connection.getMetaData().getTables(null, null, "FEEDS", null);
            if (!feedtable.next()) {
                statement.execute(SQL_CREATE_FEEDS);
            }
            ResultSet entirestable = connection.getMetaData().getTables(null, null, "ENTIES", null);
            if (!entirestable.next()) {
                statement.execute(SQL_CREATE_ENTRIES);
            }
            connection.close();
        } catch (InstantiationException e) {
            throw new SavanException(e);
        } catch (IllegalAccessException e) {
            throw new SavanException(e);
        } catch (ClassNotFoundException e) {
            throw new SavanException(e);
        } catch (SQLException e) {
            throw new SavanException(e);
        }

    }

    public Connection getConnection() throws SavanException {
        try {
            /*
               The connection specifies create=true to cause
               the database to be created. To remove the database,
               remove the directory derbyDB and its contents.
               The directory derbyDB will be created under
               the directory that the system property
               derby.system.home points to, or the current
               directory if derby.system.home is not set.
             */
            return DriverManager.getConnection(protocol +
                                               "derbyDB;create=true", props);
        } catch (SQLException e) {
            throw new SavanException(e);
        }

    }


    public void addFeed(String id, String title, Date lastEditedtime, String author)
            throws SavanException {

        try {
            Connection connection = getConnection();
            try {
                PreparedStatement statement = connection.prepareStatement(SQL_ADD_FEED);
                statement.setString(1, id);
                statement.setString(2, title);
                Timestamp t = new Timestamp(lastEditedtime.getTime());
                statement.setTimestamp(3, t);
                statement.setString(4, author);
                statement.executeUpdate();
            } finally {
                connection.close();
            }
        } catch (SQLException e) {
            throw new SavanException(e);
        }


    }

    public void addEntry(String id, OMElement entry) throws SavanException {
        try {
            StringWriter w = new StringWriter();
            entry.serialize(w);
            Connection connection = getConnection();
            try {
                PreparedStatement statement = connection.prepareStatement(SQL_ADD_ENTRY);
                statement.setString(1, id);
                statement.setString(2, w.getBuffer().toString());
                statement.executeUpdate();
            } finally {
                connection.close();
            }
        } catch (SQLException e) {
            throw new SavanException(e);
        } catch (XMLStreamException e) {
            throw new SavanException(e);
        }
    }


    public OMElement getFeedAsXml(String feedId) throws SavanException {

        try {
            Connection connection = getConnection();
            try {
                PreparedStatement statement = connection.prepareStatement(SQL_GET_FEED_DATA);
                statement.setString(1, feedId);
                ResultSet results = statement.executeQuery();
                if (results.next()) {
                    String title = results.getString("title");
                    Timestamp updatedTime = results.getTimestamp("updated");
                    String author = results.getString("author");

                    Feed feed = new Feed(title, feedId, author, updatedTime);

                    statement.close();

                    statement = connection.prepareStatement(SQL_GET_ENTRIES_4_FEED);
                    statement.setString(1, feedId);
                    results = statement.executeQuery();
                    while (results.next()) {
                        String entryAsStr = results.getString("content");
                        InputStream atomIn = new ByteArrayInputStream(entryAsStr.getBytes());
                        XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(atomIn,
                                                                                    MessageContext.DEFAULT_CHAR_SET_ENCODING);
                        StAXBuilder builder = new StAXOMBuilder(feed.getFactory(), xmlreader);
                        feed.addEntry(builder.getDocumentElement());
                    }
                    return feed.getFeedAsXml();
                } else {
                    throw new SavanException("No such feed " + feedId);
                }
            } finally {
                connection.close();
            }
        } catch (SQLException e) {
            throw new SavanException(e);
        } catch (XMLStreamException e) {
            throw new SavanException(e);
        }
    }
}
