/*
 * Created on 2006/12/27
 *
 *
 * Copyright(c) 2006 Yoshimasa Matsumoto
 */
package netwatcher.networkcamera.model;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;

import netjfwatcher.database.access.control.DatabaseConnectionException;
import netjfwatcher.database.access.model.LastCheckTimeUpDate;
import netjfwatcher.engine.alarm.AlarmMessageMake;
import netjfwatcher.engine.alarm.AlarmMessageResource;
import netjfwatcher.engine.alarm.AlarmRecovery;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;


public class HttpAccess {


    /* ロギング */
    private static Logger logger = null;

    /**
     * HTTPにてURLをチェックするインスタンスを生成します。
     *
     */
    public HttpAccess() {
        logger = Logger.getLogger(this.getClass().getName());
        
    }


    public Image getURLImage(
        final String ipaddress, String targetURL, Display display, int httpTimeout, String userName, String password) {
        

    	Image cameraImage = null;
        logger.info("HTTP GET : " + targetURL);
        
       HttpAuthenticator httpAuth = new HttpAuthenticator(userName, password);
       Authenticator.setDefault(httpAuth);
       
        try {
            // URLクラスのインスタンスを生成
            URL accessURL = new URL(targetURL);
            
            HttpURLConnection urlConn =
                (HttpURLConnection) accessURL.openConnection();

            urlConn.setConnectTimeout(httpTimeout);
            urlConn.setReadTimeout(httpTimeout);
            urlConn.setRequestMethod("GET");
            urlConn.setInstanceFollowRedirects(false);

            /*
             * urlconn.setRequestProperty("Accept-Language",
             *  "ja;q=0.7,en;q=0.3");
             */
            urlConn.setRequestProperty(
                "User-Agent", "NetJFWatcher network camera plugin");
            urlConn.setRequestProperty("Accept-Language", "ja");
            urlConn.connect();
            
            cameraImage = getImage(ipaddress, urlConn, display);
            
            urlConn.disconnect();
        } catch (IllegalArgumentException e) {
            logger.warning(
                "IllegalArgumentException : " + e.getMessage() + " "
                + targetURL);

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress,
                "IllegalArgumentException : " + e.getMessage() + " "
                + targetURL);
        } catch (SocketTimeoutException e) {
            /*
             * Connect TimeoutまたRead Timeout異常等Socket
             * Timeout
             */
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress,
                "SocketTimeoutException : " + e.getMessage() + " (set timeout="
                + httpTimeout + "ms)");
        } catch (UnknownHostException e) {
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress, "UnknownHostException : " + e.getMessage());
        } catch (MalformedURLException e) {
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress, "MalformedURLException : " + e.getMessage());
        } catch (FileNotFoundException e) {
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress, "FileNotFoundException : " + e.getMessage());
        } catch (ConnectException e) {
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress, "ConnectException : " + e.getMessage());
        } catch (IOException e) {
            logger.warning(e.getMessage());

            AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
            makeAlarm.setHTTPGetError(
                ipaddress, "IOException : " + e.getMessage());
        }

        try {
            /* 監視ノード最終チェック時間更新 */
            LastCheckTimeUpDate updateLastCheckTime =
                LastCheckTimeUpDate.getInstance();
            updateLastCheckTime.updateCheckTime(ipaddress);
        } catch (DatabaseConnectionException e) {
            logger.warning(e.getMessage());
            e.printStackTrace();
        } catch (SQLException e) {
            logger.warning(e.getMessage());
            e.printStackTrace();
        }
        
        return cameraImage;
    }


    
    private Image getImage(
        final String ipaddress, final HttpURLConnection urlConnecrion, Display display)
        throws SocketTimeoutException, IOException {

    	Image cameraImage = null;
        /* データ読み込みStream */
        InputStream urlInputStream = null;

        try {
            /* レスポンスコードチェック */
            int responseCode = urlConnecrion.getResponseCode();
            String responseMessage = urlConnecrion.getResponseMessage();

            if (responseCode != HttpURLConnection.HTTP_OK) {
                /* レスポンスコード200以外の時にアラームセット */
                logger.warning(
                    "ResponseCode [" + responseCode + "] "
                    + "ResponseMessage [" + responseMessage + "]");

                AlarmMessageMake makeAlarm = AlarmMessageMake.getInstance();
                makeAlarm.setHTTPGetError(
                    ipaddress,
                    "ResponseCode [" + responseCode + "] "
                    + "ResponseMessage [" + responseMessage + "]");

                /* 異常応答時のHeaderロギング */
                Map headers = urlConnecrion.getHeaderFields();
                Iterator it = headers.keySet().iterator();
                logger.warning("Response headers:");

                while (it.hasNext()) {
                    String key = (String) it.next();
                    logger.warning("  " + key + ": " + headers.get(key));
                }

                return null;
            }


            if (
                AlarmRecovery.getInstance().isOccurredAlarmId(
                        ipaddress, AlarmMessageResource.HTTP_GET_ERROR)) {
                /* 復旧セット */
                AlarmMessageMake message = AlarmMessageMake.getInstance();
                message.setRecoveryHTTPGetError(
                    ipaddress,
                    "ResponseCode [" + responseCode + "] "
                    + "ResponseMessage [" + responseMessage + "]");
            }


                /*
                 * Header表示出力
                 */
                Map headers = urlConnecrion.getHeaderFields();
                Iterator it = headers.keySet().iterator();

                while (it.hasNext()) {
                    String key = (String) it.next();
                    System.out.println("  " + key + ": " + headers.get(key));
                }

                /* Response Code表示出力 */
                System.out.println(
                    "ResponseCode[" + responseCode + "] " + "ResponseMessage["
                    + responseMessage + "]");

                urlInputStream = urlConnecrion.getInputStream();
                cameraImage = new Image(display, urlInputStream);
                

        } finally {

            if (urlInputStream != null) {
                try {
                    urlInputStream.close();
                } catch (IOException e1) {
                    logger.warning(e1.getMessage());
                    e1.printStackTrace();
                }
            }
        }

        return cameraImage;
    }
}
