/*
 * Copyright 1&1 Internet AG, https://github.com/1and1/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.oneandone.stool.server.ui;

import net.oneandone.stool.server.Server;
import net.oneandone.stool.server.docker.Engine;
import net.oneandone.stool.server.stage.Stage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@RestController
@RequestMapping("/ui/stages")
public class StageController {
    @Autowired
    private Server server;

    private final Engine engine;
    private final Collection<Stage> stagesCache;
    private long lastCacheRenew;

    public StageController() throws IOException {
        engine = Engine.create(); // TODO
        stagesCache = new ArrayList<>();
        lastCacheRenew = 0L;
    }

    private Collection<Stage> stages(Server session) throws IOException {
        List<Stage> lst;

        if (System.currentTimeMillis() - lastCacheRenew > 4000) {
            stagesCache.clear();
            lst = session.listAll();
            Collections.sort(lst, new Comparator<Stage>() {
                @Override
                public int compare(Stage left, Stage right) {
                    boolean lr;
                    boolean rr;

                    lr = left.configuration.expire.isReserved();
                    rr = right.configuration.expire.isReserved();
                    if (lr == rr) {
                        return left.getName().compareToIgnoreCase(right.getName());
                    } else {
                        return lr ? -1 : 1;
                    }
                }
            });
            stagesCache.addAll(lst);
            lastCacheRenew = System.currentTimeMillis();
        }
        return stagesCache;
    }

    @RequestMapping(method = RequestMethod.GET)
    public Collection<Stage> stages() throws IOException {
        return stages(server);
    }

    @RequestMapping(method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView stagesAsHtml(ModelAndView modelAndView) throws IOException {
        modelAndView.setViewName("stages");
        modelAndView.addObject("engine", engine);
        modelAndView.addObject("userManager", server.userManager);
        modelAndView.addObject("stages", stages(server));

        return modelAndView;
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ExceptionExport> handleApiException(HttpServletRequest request, Throwable e) {
        // TODO: really report this? maybe it's just a 404 ...
        server.reportException((String) request.getAttribute("command"), "StageController.handleApiException", e);
        return new ResponseEntity<>(new ExceptionExport(e), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    private static class ExceptionExport {
        private final String message;
        ExceptionExport(Throwable e) {
            message = e.getMessage();
        }

        private String getMessage() {
            return message;
        }
    }
}

@@ -1667,90 +1667,8 @@
 ine;
-%0A    private final Collection%3CStage%3E stagesCache;%0A    private long lastCacheRenew;
 %0A%0A  
@@ -1761,78 +1761,8 @@
 ODO%0A
-        stagesCache = new ArrayList%3C%3E();%0A        lastCacheRenew = 0L;%0A
     
@@ -1798,29 +1798,13 @@
 ge%3E 
-stages(Server session
+list(
 ) th
@@ -1860,124 +1860,20 @@
     
-if (System.currentTimeMillis() - lastCacheRenew %3E 4000) %7B%0A            stagesCache.clear();%0A            lst = session
+lst = server
 .lis
@@ -1876,28 +1876,24 @@
 .listAll();%0A
-    
         Coll
@@ -1948,20 +1948,16 @@
         
-    
 @Overrid
@@ -1958,20 +1958,16 @@
 verride%0A
-    
         
@@ -2024,36 +2024,32 @@
                 
-  
-  
 boolean lr;%0A    
@@ -2044,20 +2044,16 @@
 ean lr;%0A
-    
         
@@ -2073,20 +2073,16 @@
 an rr;%0A%0A
-    
         
@@ -2150,20 +2150,16 @@
         
-    
 rr = rig
@@ -2212,20 +2212,16 @@
         
-    
 if (lr =
@@ -2240,36 +2240,32 @@
                 
- 
-   
 return left.getN
@@ -2324,20 +2324,16 @@
         
-    
 %7D else %7B
@@ -2345,36 +2345,32 @@
                 
-   
- 
 return lr ? -1 :
@@ -2385,34 +2385,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -2413,20 +2413,16 @@
         
- 
-   
 %7D);%0A    
@@ -2429,275 +2429,18 @@
     
-    stagesCache.addAll(lst);%0A            lastCacheRenew = System.currentTimeMillis();%0A        %7D%0A        return stagesCache;%0A    %7D%0A%0A    @RequestMapping(method = RequestMethod.GET)%0A    public Collection%3CStage%3E stages() throws IOException %7B%0A        return stages(server)
+return lst
 ;%0A  
@@ -2494,46 +2494,8 @@
 .GET
-, produces = MediaType.TEXT_HTML_VALUE
 )%0A  
@@ -2783,21 +2783,13 @@
 s%22, 
-stages(server
+list(
 ));%0A
@@ -2827,683 +2827,7 @@
    %7D
-%0A%0A    @ExceptionHandler(Exception.class)%0A    public ResponseEntity%3CExceptionExport%3E handleApiException(HttpServletRequest request, Throwable e) %7B%0A        // TODO: really report this? maybe it's just a 404 ...%0A        server.reportException((String) request.getAttribute(%22command%22), %22StageController.handleApiException%22, e);%0A        return new ResponseEntity%3C%3E(new ExceptionExport(e), HttpStatus.INTERNAL_SERVER_ERROR);%0A    %7D%0A%0A    private static class ExceptionExport %7B%0A        private final String message;%0A        ExceptionExport(Throwable e) %7B%0A            message = e.getMessage();%0A        %7D%0A%0A        private String getMessage() %7B%0A            return message;%0A        %7D%0A    %7D
 %0A%7D%0A

remove cache