package com.eactive.eai.rms.client.agent;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;

import com.eactive.eai.rms.client.SocketClient;
import com.eactive.eai.rms.client.context.RmsProperties;
import com.eactive.eai.rms.onl.vo.SmsVO;

import org.apache.mina.common.ByteBuffer;

/**
 * The Class SmsAgent.
 * <ul>
 * <li>1. Function : SMS내용을 정해진 주기 마다 RMS 서버로 전송 합니다. </li>
 * <li>2. Summary :</li>
 * <li>3. Notification :</li>
 * </ul>
 * 
 * @author  : $Author: 윤창용 $
 * @version : $Revision: 1.8 $
 */
public class SmsAgent extends AbstractScheduledAgent {

    private SocketClient socketClient = null;
    private RmsProperties rmsProperties;
	/**
	 * sms log data format
	 * 월일 시간[건수]인스턴스 메시지
	 * 1103 13:56:58.715[1]mcc11 HTTP호출에러|MUTMIAS00000170S1
	 */
    public void run() {
        File logFile = null;
        RandomAccessFile raf = null;
        FileChannel fileChannel = null;
        ByteBuffer buffer = null;
        SmsVO smsVO = null;
        try {
            int maxLine = rmsProperties.getIntProperty(
                    RmsProperties.SMS_AGENT_MAXLINE, 1);

            String DEFAULT_LOG_PATH = rmsProperties.getStringProperty(
                    RmsProperties.DEFAULT_LOG_PATH, "/fslog/eai/");
            String instanceName = rmsProperties
                    .getStringProperty(RmsProperties.EAI_SERVER_INSTANCE_NAME);
            String SMS_LOG_FILE = rmsProperties.getStringProperty(RmsProperties.SMS_LOG_FILE, "sms.log");
            String SMS_LOG_FILE_ENCODING = rmsProperties.getStringProperty(RmsProperties.SMS_LOG_FILE_ENCODE, "UTF-8");

            int bufferSize = maxLine * 100;

            // 마지막 5라인만 보낸다. 
            logFile = new File(DEFAULT_LOG_PATH + instanceName + "/"
                    + SMS_LOG_FILE);
            raf = new RandomAccessFile(logFile, "r");
            fileChannel = raf.getChannel();
            buffer = ByteBuffer.allocate(bufferSize);

            if (raf.length() <= bufferSize) {
                // bufferSize 바이트 보다 작으면 
                fileChannel.read(buffer.buf());
            } else {
                // bufferSize 바이트 보다 크면 뒤에서 부터 bufferSize 바이트만 읽는다. 
                fileChannel.read(buffer.buf(), raf.length() - bufferSize);
                buffer.flip();
                String searchString = System.getProperty("line.separator");
                int position = findStringPosition(buffer, searchString, SMS_LOG_FILE_ENCODING);
                if (position != -1) {
                	buffer.position(position + searchString.length() );
                	buffer.compact();
                }
            }

            buffer.flip();

            //String text = buffer.getString(Charset.defaultCharset().newDecoder());
            String text = buffer.getString(Charset.forName(SMS_LOG_FILE_ENCODING).newDecoder());

            String[] texts = text.split(System.lineSeparator());

            smsVO = (SmsVO) applicationContext.getBean("smsVo");
            LinkedList<String> list = new LinkedList<String>();

            int currentLine = 0;
            for (int i = texts.length - 1; i >= 0 && currentLine < maxLine; i--) {
                currentLine++;
                if (logger.isDebugEnabled()) {
                    logger.debug(texts[i]);
                }

                if (texts[i] != null && !texts[i].startsWith("[")) {
                    list.addLast(texts[i]);
                }
            }

            smsVO.setMessage(list);

            socketClient.send(smsVO);
            logger.debug("SEND SmsAgent : " + smsVO );

        } catch (FileNotFoundException fe) {
            sendFileNotFoundMessage(logFile);
        } catch (Exception e) {
            logger.error("SMS 메세지를 수집 하는 중 에러가 발생 하였습니다. ", e);
        } finally {
            if (buffer != null) {
                buffer.release();
            }

            if (fileChannel != null) {
                try {
                    fileChannel.close();
                } catch (IOException e) {
                }
            }

            if (raf != null) {
                try {
                    raf.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private void sendFileNotFoundMessage(File logFile) {
        try {
            // 0702 00:00:08.371
            SmsVO smsVO = (SmsVO) applicationContext.getBean("smsVo");
            SimpleDateFormat format = new SimpleDateFormat("MMdd HH:mm:ss.SSS");
            ArrayList<String> list = new ArrayList<String>();
            list.add(format.format(new Date()) + "SMS 로그 파일을 찾을 수 없습니다 : "
                    + logFile.getPath());
            smsVO.setMessage(list);
            socketClient.send(smsVO);
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        SmsAgent s = new SmsAgent();
        s.run();
    }

    public void setSocketClient(SocketClient socketClient) {
        this.socketClient = socketClient;
    }

    public void setRmsProperties(RmsProperties rmsProperties) {
        this.rmsProperties = rmsProperties;
    }
	private int findStringPosition(ByteBuffer buffer, String searchString, String encoding) {
		byte[] searchBytes = searchString.getBytes(Charset.forName(encoding));
		for (int i = 0; i < buffer.remaining(); i++) {
			boolean found = true;
			for (int j = 0; j < searchBytes.length; j++) {
				if (buffer.get(i + j) != searchBytes[j]) {
					found = false;
					break;
				}
			}
			if (found) {
				return i;
			}
		}
		return -1;
	}
}
