import junit.framework.Test;
import junit.framework.TestSuite;
import junit.framework.TestCase;

import java.util.*;
import java.sql.SQLException;

import cirrus.hibernate.*;

public class ArticleTest extends TestCase{
    public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
    }

    public static Test suite() {
        TestSuite suite = new TestSuite(ArticleTest.class);
        return suite;
    }


    public void testUpdateAndSave() {

        Datastore ds;
        ds = Hibernate.createDatastore();

        SessionFactory sf = null;

        Session session = null;
        try {
            ds.storeClass(Article.class);
            sf = ds.buildSessionFactory();
            session = sf.openSession();

            Article correctArticle = new Article("Title", new Date(), "Content", true);

            try {
                System.out.println("----------------- saving correct article");
                session.save(correctArticle);
                System.out.println("----------------- /saving correct article");
            } catch (Exception e) {
                // it should NOT fail here
                fail(e.getMessage());
            }

            // first parameter - title is NOT NULL, so this should not be saved
            Article incorrectArticle = new Article(null, new Date(), "Content", true);

            boolean failed;
            failed = false;
            try {
                System.out.println("----------------- saving incorrect article");
                session.save(incorrectArticle);
            } catch (SQLException e) {
                // this must fail
                failed = true;
            } finally {
                System.out.println("----------------- /saving incorrect article");
            }

            assertTrue(failed);

            // now I need to close session, because after exception it can not be used
            session.close();
            session = sf.openSession();

            // now I will "break" the correct article and try to update it.

            correctArticle.setTitle(null);

            failed = false;
            try {
                System.out.println("----------------- updating 'broken' article");
                System.out.println("Article title before is: "+correctArticle.getTitle());
                session.update(correctArticle);
                System.out.println("Article title after update is: "+correctArticle.getTitle());
                session.flush();
                System.out.println("Article title after flush is: "+correctArticle.getTitle());
            } catch (SQLException e) {
                // since title is set to null, it should fail here
                failed = true;
            } catch (HibernateException e) {
                fail(e.getMessage());
            } finally {
                System.out.println("----------------- /updating 'broken' article");
            }
            System.out.println("The title of article is: '"+correctArticle.getTitle()+"' and update failed: "+failed);

            // again, there was (maybe) an exception
            session.close();
            session = sf.openSession();

            Article loadedArticle = (Article) session.load(Article.class, new Long(correctArticle.getId()));

            System.out.println("The title of loaded article is: '"+loadedArticle.getTitle()+"'");

            assertTrue(failed);

            session.flush();
        } catch (HibernateException e){
            System.out.println("-------- Hibernate Exception --------");
            e.printStackTrace();
            System.out.println("-------- /Hibernate Exception --------");
        } catch (SQLException e) {
            System.out.println("----------- SQL Exception -----------");
            e.printStackTrace();
            System.out.println("----------- /SQL Exception -----------");
        }finally {
            try{
                session.close();
            } catch (Exception e) {
                System.out.println("-------- session.close() --------");
                e.printStackTrace();
                System.out.println("-------- /session.close() --------");
            }
        }
    }
}
