package yanagishima.util;

import io.airlift.units.DataSize;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class HistoryUtil {

    public static void createHistoryResult(HashMap<String, Object> retVal, int limit, String datasource, String queryid, String queryString, String fetchResultTimeString) {
        retVal.put("queryString", queryString);
        retVal.put("finishedTime", fetchResultTimeString);

        Path errorFilePath = PathUtil.getResultFilePath(datasource, queryid, true);
        if (errorFilePath.toFile().exists()) {
            try (BufferedReader br = Files.newBufferedReader(errorFilePath, StandardCharsets.UTF_8)) {
                String line = br.readLine();
                retVal.put("error", line);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            List<List<String>> rowDataList = new ArrayList<List<String>>();
            int lineNumber = 0;
            try (BufferedReader br = Files.newBufferedReader(PathUtil.getResultFilePath(datasource, queryid, false), StandardCharsets.UTF_8)) {
                CSVParser parse = CSVFormat.EXCEL.withDelimiter('\t').withNullString("\\N").parse(br);
                for (CSVRecord csvRecord : parse) {
                    List<String> columnList = new ArrayList<>();
                    for(String column : csvRecord) {
                        columnList.add(column);
                    }
                    if (lineNumber == 0) {
                        retVal.put("headers", columnList);
                    } else {
                        if (queryString.toLowerCase().startsWith("show") || lineNumber <= limit) {
                            rowDataList.add(columnList);
                        }
                    }
                    lineNumber++;

                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            retVal.put("results", rowDataList);
            retVal.put("lineNumber", Integer.toString(lineNumber));
            LocalDateTime submitTimeLdt = LocalDateTime.parse(queryid.substring(0, "yyyyMMdd_HHmmss".length()), DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            ZonedDateTime submitTimeZdt = submitTimeLdt.atZone(ZoneId.of("GMT", ZoneId.SHORT_IDS));
            ZonedDateTime fetchResultTime = ZonedDateTime.parse(fetchResultTimeString);
            long elapsedTimeMillis = ChronoUnit.MILLIS.between(submitTimeZdt, fetchResultTime);
            retVal.put("elapsedTimeMillis", elapsedTimeMillis);
            try {
                long size = Files.size(PathUtil.getResultFilePath(datasource, queryid, false));
                DataSize rawDataSize = new DataSize(size, DataSize.Unit.BYTE);
                retVal.put("rawDataSize", rawDataSize.convertToMostSuccinctDataSize().toString());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

}

@@ -237,16 +237,50 @@
 eption;%0A
+import java.io.InputStreamReader;%0A
 import j
@@ -313,16 +313,16 @@
 arsets;%0A
-
 import j
@@ -1487,57 +1487,30 @@
     
-try (BufferedReader br = Files.newBufferedReader(
+Path resultFilePath = 
 Path
@@ -1559,16 +1559,93 @@
 , false)
+;%0A            try (BufferedReader br = Files.newBufferedReader(resultFilePath
 , Standa
@@ -2287,32 +2287,100 @@
 dd(columnList);%0A
+                        %7D else %7B%0A                            break;%0A
                 
@@ -2607,24 +2607,25 @@
 wDataList);%0A
+%0A
             
@@ -2628,63 +2628,517 @@
     
-retVal.put(%22lineNumber%22, Integer.toString(lineNumber));
+try %7B%0A                ProcessBuilder pb = new ProcessBuilder(%22wc%22, %22-l%22, resultFilePath.toFile().getAbsolutePath());%0A                Process proc = pb.start();%0A                try(BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())))%7B%0A                    String line = br.readLine();%0A                    retVal.put(%22lineNumber%22, line.trim().split(%22%5C%5Cs+%22)%5B0%5D);%0A                %7D%0A            %7D catch (IOException e) %7B%0A                throw new RuntimeException(e);%0A            %7D%0A
 %0A   

use wc command to calculate line number