package com.focusit.jsflight.server.service;

import com.focusit.jsflight.server.model.Event;
import com.focusit.jsflight.server.model.Recording;
import com.focusit.jsflight.server.repository.EventRepository;
import com.focusit.jsflight.server.repository.RecordingRepository;
import com.google.gson.Gson;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * Created by doki on 14.05.16.
 */
@Service
public class RecordingsService
{
    private final static Logger LOG = LoggerFactory.getLogger(RecordingsService.class);

    private RecordingRepository recordingRepository;
    private EventRepository eventRepository;

    @Inject
    public RecordingsService(RecordingRepository recordingRepository, EventRepository eventRepository)
    {
        this.recordingRepository = recordingRepository;
        this.eventRepository = eventRepository;
    }

    public boolean importRecording(String name, InputStream stream)
    {
        String array = "";

        Recording rec = recordingRepository.findByName(name);
        if (rec == null)
        {
            rec = new Recording();
            rec.setName(name);
            rec = recordingRepository.save(rec);
        }
        Recording finalRec = rec;
        Gson gson = new Gson();

        List<CompletableFuture> operations = new ArrayList<>();

        try (InputStreamReader reader = new InputStreamReader(stream, "UTF-8"))
        {
            try (BufferedReader buffered = IOUtils.toBufferedReader(reader))
            {
                array = buffered.readLine();

                while (array != null)
                {

                    String finalArray = array;

                    operations.add(CompletableFuture.supplyAsync(() -> {
                        List<Event> lineEvents = null;
                        JSONArray events = new JSONArray(finalArray);
                        lineEvents = new ArrayList<>(events.length());

                        for (int i = 0; i < events.length(); i++)
                        {
                            JSONObject event = new JSONObject(events.get(i).toString());
                            try
                            {
                                Event e = gson.fromJson(event.toString(), Event.class);
                                if (e == null)
                                {
                                    LOG.error("e==null.\n", event.toString(4));
                                    continue;
                                }
                                lineEvents.add(e);
                            }
                            catch (Throwable t)
                            {
                                LOG.error(t.toString(), t);
                                throw t;
                            }
                        }

                        lineEvents.forEach(event -> {
                            event.setRecordingId(finalRec.getId());
                            event.setRecordName(finalRec.getName());
                        });

                        eventRepository.save(lineEvents);

                        return true;
                    }).whenCompleteAsync((aBoolean, throwable) -> {
                        if (throwable != null)
                        {
                            LOG.error(throwable.toString(), throwable);
                        }
                    }));

                    array = buffered.readLine();
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        final boolean[] result = { true };
        CompletableFuture.allOf(operations.toArray(new CompletableFuture[operations.size()])).whenComplete(
                (aVoid, throwable) -> {
                    if (throwable != null)
                    {
                        result[0] = false;
                    }
                });

        return result[0];
    }

    public List<Recording> getAllRecordings()
    {
        List<Recording> result = new ArrayList<>();
        recordingRepository.findAll().forEach(result::add);
        return result;
    }
}

@@ -742,16 +742,80 @@
 eFuture;
+%0Aimport java.util.regex.Matcher;%0Aimport java.util.regex.Pattern;
 %0A%0A/**%0A *
@@ -977,16 +977,80 @@
 .class);
+%0A    public static final String URL_BASE_TEMPLATE = %220.0.0.0:0%22;
 %0A%0A    pr
@@ -2239,63 +2239,8 @@
 %3E %7B%0A
-                        List%3CEvent%3E lineEvents = null;%0A
     
@@ -2320,32 +2320,44 @@
                 
+ List%3CEvent%3E
  lineEvents = ne
@@ -2525,16 +2525,22 @@
 ct event
+AsJson
  = new J
@@ -2677,16 +2677,20 @@
  Event e
+vent
  = gson.
@@ -2699,24 +2699,30 @@
 omJson(event
+AsJson
 .toString(),
@@ -2773,16 +2773,20 @@
    if (e
+vent
  == null
@@ -2872,26 +2872,56 @@
 or(%22
-e==null.%5Cn
+Parsed event was null. Event as JSON: %7B%7D
 %22, event
 .toS
@@ -2916,16 +2916,22 @@
 %22, event
+AsJson
 .toStrin
@@ -3009,32 +3009,427 @@
               %7D%0A
+                                LOG.info(%22Changing event's url base to template %7B%7D%22, URL_BASE_TEMPLATE);%0A                                Pattern pattern = Pattern.compile(%22%5Ehttps?://(%5B%5E:/%5D+:?%5C%5Cd*)?/.*$%22);%0A                                Matcher matcher = pattern.matcher(event.getUrl());%0A                                event.setUrl(event.getUrl().replace(matcher.group(1), URL_BASE_TEMPLATE));%0A
                 
@@ -3460,16 +3460,20 @@
 ts.add(e
+vent
 );%0A     
@@ -3619,24 +3619,26 @@
 error(t.
-toString
+getMessage
 (), t);%0A
@@ -4240,24 +4240,26 @@
 rowable.
-toString
+getMessage
 (), thro
@@ -4465,26 +4465,35 @@
     
-e.printStackTrace(
+LOG.error(e.getMessage(), e
 );%0A 

Update recording loading