package com.sample;

import com.sample.Book;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

/* CRUD code based on Sujit Reddy G's crud app:
 * http://sujitreddyg.wordpress.com/2009/10/12/building-flex-and-java-based-crud-application-using-flash-builder-4/ */

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class BookService 
{

    @WebMethod
    public int addBook(Book book) 
    {
        /* insert book into db */
        int resultCode = 0;
        Connection connection = null;
        
        if(book == null)
        {
            throw new IllegalArgumentException("Book object is invalid");
        }
        
        String bookName = book.getName();
        String bookAuthor = book.getAuthor();
        double bookPrice = book.getPrice();
        
        if(bookName == null ||
           bookAuthor == null
           )
        {
            throw new IllegalArgumentException("Book object is invalid");
        }
        
        try
        {
            
            connection = getConnection();
            PreparedStatement statement = 
                connection.prepareStatement("INSERT INTO BOOKS (" +
                                            "BOOK_NAME, BOOK_AUTHOR, BOOK_PRICE " +
                                            ") VALUES(?,?,?)");
            
            statement.setString(1, bookName);
            statement.setString(2, bookAuthor);
            statement.setDouble(3, bookPrice);
            
            int rowCount = statement.executeUpdate();
            
            if(rowCount == 1)
            {
                resultCode = 1;
            }
        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Book entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }		
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();	
                }
            }
            catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }			
        }	
        
        return resultCode;
    }

    @WebMethod
    public int updateBook(Book book)
    {
        /* update book into db */
        int resultCode = 0;
        Connection connection = null;
        
        if(book == null)
        {
            throw new IllegalArgumentException("Book object is invalid");
        }
        
        String bookName = book.getName();
        String bookAuthor = book.getAuthor();
        double bookPrice = book.getPrice();
        int bookid = book.getBookid();
        
        if(bookid <= 0 || 
           bookName == null ||
           bookAuthor == null
           )
        {
            throw new IllegalArgumentException("Book object is invalid");
        }
        
        try
        {
            
            connection = getConnection();
            PreparedStatement statement = 
                connection.prepareStatement("UPDATE BOOKS SET " +
                                            "BOOK_NAME = ?, BOOK_AUTHOR = ?, BOOK_PRICE=? " +
                                            "WHERE BOOK_ID = ?");
            
            statement.setString(1, bookName);
            statement.setString(2, bookAuthor);
            statement.setDouble(3, bookPrice);
            statement.setInt(4, bookid);
            
            int rowCount = statement.executeUpdate();
            
            if(rowCount == 1)
            {
                resultCode = 1;
            }
        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Book entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }		
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();	
                }
            }
            catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }			
        }	
        
        return resultCode;
    }

    @WebMethod
    public int deleteBook(int bookid)
    {
        int result = 0;
        Connection connection = null;
        
        if( bookid <= 0 )
        {
            throw new IllegalArgumentException("Book id is invalid");
        }
        
        try
        {
            connection = getConnection();
            PreparedStatement bookStatement;
            
            bookStatement = connection.prepareStatement("DELETE FROM BOOKS WHERE BOOK_ID = ?");
            bookStatement.setInt(1, bookid);
            int rowCount = bookStatement.executeUpdate();
            if(rowCount == 1)
            {
                result = 1;
            }	
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }		
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();	
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }			
        }		
        return result;
    }

    @WebMethod
    public Book[] getBooks()
    {
        /* insert book into db */
        ArrayList<Book> books = new ArrayList<Book>();
        Connection connection = null;
        
        try
        {
            connection = getConnection();
            PreparedStatement statement = connection.prepareStatement("SELECT * FROM BOOKS");
            
            ResultSet rs = statement.executeQuery();
            books = marshallToBook(rs);
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();	
                }
            }
            catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }			
        }	
        int len = books.size();
        Book[] fBooks = new Book[len];
        books.toArray(fBooks);
        return fBooks;

    }

    public void BookService()
    {

    }

    
    
    private Connection getConnection()throws Exception
    {
        Connection connection = null;
        try 
        {
            Class.forName("org.gjt.mm.mysql.Driver").newInstance();
        }
        catch (Exception e) 
        {
            throw e;
        }
        
        try 
        {
            connection = DriverManager.getConnection(
                "jdbc:mysql://localhost/" + "DatabaseName", "UserName","Password");
        }
        catch (SQLException sqlException) 
        {
            throw sqlException;
        }		
        return connection;		
    }

    private ArrayList<Book> marshallToBook(ResultSet rs) throws Exception
    {
        ArrayList<Book> books = new ArrayList<Book>();
        Book book;
        while(rs.next())
        {
            book = new Book();
            book.setName(rs.getString("BOOK_NAME"));
            book.setAuthor(rs.getString("BOOK_AUTHOR"));
            book.setPrice(rs.getDouble("BOOK_PRICE"));
            book.setBookid(rs.getInt("BOOK_ID"));
            
            books.add(book);
        }		
        return books;
    }
       
    public static void main(String[] args)
    {
        // create and publish an endpoint
        BookService bookservice = new BookService();
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/books", bookservice);
    }
}