/**
 * Copyright (c) 2016-2018 by the respective copyright holders.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package de.csdev.ebus.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.csdev.ebus.command.IEBusCommandMethod;
import de.csdev.ebus.service.parser.IEBusParserListener;

/**
 *
 * @author Christian Sowada - Initial contribution
 */
public class EBusTelegramWriter implements IEBusParserListener {

    private final Logger logger = LoggerFactory.getLogger(EBusTelegramWriter.class);

    private BufferedWriter writerResolved;

    private BufferedWriter writerUnresolved;

    private File loggingDirectory;

    public EBusTelegramWriter(File loggingDirectory) {
        this.loggingDirectory = loggingDirectory;
    }

    @Override
    public void onTelegramResolved(IEBusCommandMethod commandChannel, Map<String, Object> result, byte[] receivedData,
            Integer sendQueueId) {

        try {
            if (writerResolved == null) {
                writerResolved = open("ebus-resolved.csv");
            }
            String comment = String.format("%s > %s.%s", commandChannel.getMethod(),
                    commandChannel.getParent().getParentCollection().getId(), commandChannel.getParent().getId());

            write(writerResolved, receivedData, comment);

        } catch (IOException e) {
            logger.error("error!", e);
        }

    }

    @Override
    public void onTelegramResolveFailed(IEBusCommandMethod commandChannel, byte[] receivedData, Integer sendQueueId,
            String exceptionMessage) {

        try {
            if (writerUnresolved == null) {
                writerUnresolved = open("ebus-unresolved.csv");
            }
            write(writerUnresolved, receivedData, "");

        } catch (IOException e) {
            logger.error("error!", e);
        }
    }

    /**
     * Opens a CSV file
     *
     * @param csvFile The file object
     * @throws IOException
     */
    private BufferedWriter open(String filename) throws IOException {

        // File loggingFolder = new File(System.getProperty("openhab.logdir"));
        File file = new File(loggingDirectory, filename);

        BufferedWriter writer = new BufferedWriter(new FileWriter(file));

        if (!file.exists()) {
            file.createNewFile();
        }

        logger.warn(file.getAbsolutePath());

        writer.write("Date/Time;");
        writer.write("SRC;");
        writer.write("DST;");
        writer.write("CMD;");
        writer.write("REMAIN_DATA;");

        writer.newLine();
        writer.flush();

        return writer;
    }

    /**
     * Close the CSV file
     */
    public void close() {
        try {
            if (writerResolved != null) {
                writerResolved.flush();
                writerResolved.close();
                writerResolved = null;
            }

            if (writerUnresolved != null) {
                writerUnresolved.flush();
                writerUnresolved.close();
                writerUnresolved = null;
            }

        } catch (IOException e) {
            logger.error("error!", e);
        }
    }

    private void write(BufferedWriter writer, byte[] receivedData, String comment) throws IOException {

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();

        writer.write(df.format(date));
        writer.write(";");

        writer.write('"' + EBusUtils.toHexDumpString(receivedData[0]) + '"');
        writer.write(";");

        writer.write('"' + EBusUtils.toHexDumpString(receivedData[1]) + '"');
        writer.write(";");

        byte[] command = Arrays.copyOfRange(receivedData, 2, 4);
        writer.write('"' + EBusUtils.toHexDumpString(command).toString() + '"');
        writer.write(";");

        byte[] rest = Arrays.copyOfRange(receivedData, 4, receivedData.length);
        writer.write('"' + EBusUtils.toHexDumpString(rest).toString() + '"');
        writer.write(";");

        writer.write(comment);

        writer.newLine();
        writer.flush();
    }
}

@@ -3699,32 +3699,68 @@
  IOException %7B%0A%0A
+        synchronized (writer) %7B%0A    
         DateForm
@@ -3816,24 +3816,28 @@
 %22);%0A        
+    
 Date date = 
@@ -3849,32 +3849,36 @@
 ate();%0A%0A        
+  
+  
 writer.write(df.
@@ -3892,32 +3892,36 @@
 date));%0A        
+    
 writer.write(%22;%22
@@ -3916,32 +3916,36 @@
 er.write(%22;%22);%0A%0A
+    
         writer.w
@@ -3998,32 +3998,36 @@
 ata%5B0%5D) + '%22');%0A
+    
         writer.w
@@ -4038,32 +4038,36 @@
 (%22;%22);%0A%0A        
+    
 writer.write('%22'
@@ -4120,32 +4120,36 @@
 + '%22');%0A        
+   
+ 
 writer.write(%22;%22
@@ -4144,32 +4144,36 @@
 er.write(%22;%22);%0A%0A
+    
         byte%5B%5D c
@@ -4221,32 +4221,36 @@
  2, 4);%0A        
+  
+  
 writer.write('%22'
@@ -4306,32 +4306,36 @@
 + '%22');%0A        
+    
 writer.write(%22;%22
@@ -4342,24 +4342,28 @@
 );%0A%0A        
+ 
+   
 byte%5B%5D rest 
@@ -4422,16 +4422,20 @@
 ength);%0A
+    
         
@@ -4504,32 +4504,36 @@
 + '%22');%0A        
+    
 writer.write(%22;%22
@@ -4536,32 +4536,36 @@
 (%22;%22);%0A%0A        
+   
+ 
 writer.write(com
@@ -4572,32 +4572,36 @@
 ment);%0A%0A        
+    
 writer.newLine()
@@ -4602,32 +4602,36 @@
 Line();%0A        
+  
+  
 writer.flush();%0A
@@ -4626,20 +4626,31 @@
 er.flush();%0A
+        %7D%0A%0A
     %7D%0A%7D%0A

Synchronize log file writers