/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Darren Marvin
//      Created date:           2004/04/30
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: None
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package uk.ac.soton.itinnovation.gemss.transportmessaging.connection.file;

import java.io.*;
import java.net.*;
import java.util.logging.*;
import uk.ac.soton.itinnovation.gemss.transportmessaging.connection.*;
import uk.ac.soton.itinnovation.gemss.transportmessaging.messaging.*;


/**
 * FileConnection enables connections to local file system
 */
public class FileConnection implements Connection {

    private static Logger mLogger = Logger.getLogger("uk.ac.soton.itinnovation.gemss.transportmessaging.connection.FileConnection");
    private File file = null;
    private FileInputStream fsInStream = null;

    /**
     * Full initialistion constructor
     * @param url
     * @throws ConnectionException
     */
    public FileConnection(URL url) throws ConnectionException {
        try{
            file = new File(url.getPath());
        }
        catch(Exception ex) {
            mLogger.log(Level.SEVERE,"Unable to obtain file resource, please check configuration",ex);
            throw new ConnectionException("Unable to obtain file resource, please check configuration");
        }
    }

    /**
     * Send the supplied data within the input stream to the connection endpoint associated with
     * the concrete instance
     * @param in inputstream data source
     * @param packetLength size of the data source
     * @param properties name value pairs useful for the connection
     * @return response from the server - there is no response stream hence the inputstream has zero length for this type of connection
     * @throws ConnectionException
     */
    public ConnectionResponse send(Message message) throws ConnectionException {
        try{
            //this essentially writes to the file URL, or tries to given file permissions - there is no response obviously
            if(file==null) {
                throw new ConnectionException("File resource is not available");
            }
            if(!file.exists()) {
                if(!file.createNewFile())
                    throw new ConnectionException("Unable to create file '" + file.getAbsolutePath() + "', please check permissions");
            }
            FileOutputStream fsOutStream = new FileOutputStream(file);
            message.writeTo(fsOutStream);
            return new ConnectionResponse(new ByteArrayInputStream(new byte[0]),message.getMessageContext().getConnectionProperties());
        }
        catch(IOException ex) {
            if(fsInStream!=null) {
                try {
                    fsInStream.close();
                }
                catch(IOException e) {

                }
            }
            mLogger.log(Level.SEVERE,"Unable to write to resource '" + file.getAbsolutePath() + "', please check it exists",ex);
            throw new ConnectionException("Unable to write to resource '" + file.getAbsolutePath() + "', please check it exists");
        }
        catch(MessagingException ex) {
           mLogger.log(Level.SEVERE,"Messaging failure when sending to '" + file.getAbsoluteFile() +"', logs may hold further information.",ex);
           throw new ConnectionException("Messaging failure when sending to '" + file.getAbsoluteFile() +"'");
        }
    }

    /**
     * Retrieve the inputstream for the resource pointed to by this connection
     * @return inputstream to resource
     * @throws ConnectionException
     */
    public InputStream getResourceInputStream() throws ConnectionException {
        try{
            if(file==null)
                throw new ConnectionException("File Resource is not available");
            if(fsInStream!=null) {
                fsInStream.close();
            }
            fsInStream = new FileInputStream(file);
            return fsInStream;
        }
        catch(IOException ex) {
            if(fsInStream!=null) {
                try{
                    fsInStream.close();
                }
                catch(IOException e) {

                }
            }
            mLogger.log(Level.SEVERE,"Unable to read file '" + file.getAbsolutePath() + "'",ex);
            throw new ConnectionException("Unable to read file '" + file.getAbsolutePath() + "'");
        }
    }

    /**
     * Release the connection and any associated resources.
     */
    public void releaseConnection() {
        try{
            if(fsInStream!=null)
                fsInStream.close();
        }
        catch(IOException ex) {
            mLogger.log(Level.WARNING,"Unable to release connection to file '" + file.getAbsolutePath() + "'",ex);
            //did the best we could
        }
    }

}

