// Path: src/main/java/com/indeed/proctor/webapp/db/Environment.java
// public enum Environment {
//     WORKING("trunk", 0),
//     QA("qa", 1),
//     PRODUCTION("production", 2);
// 
//     private final String name;
//     private final int precedence;
//     private Environment(final String name, final int precedence) {
//         this.name = name;
//         this.precedence = precedence;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public int getPrecedence() {
//         return precedence;
//     }
// 
//     private static final Map<String, Environment> LOOKUP = Maps.uniqueIndex(ImmutableList.copyOf(Environment.values()), Functions.toStringFunction());
//     public static Environment fromName(String name) {
//         if(name == null) {
//             return null;
//         } else {
//             return LOOKUP.get(name.toLowerCase());
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return this.getName();
//     }
// }
// 
// Path: src/main/java/com/indeed/proctor/webapp/model/WebappConfiguration.java
// @Component
// public class WebappConfiguration {
//     private final boolean useCompiledCSS;
//     private final boolean useCompiledJavaScript;
//     private final int verifyHttpTimeout;
//     private final int verifyExecutorThreads;
// 
//     @SuppressWarnings({"SpringJavaAutowiringInspection"})
//     @Autowired
//     public WebappConfiguration(@Value("${use.compiled.css:true}") boolean useCompiledCSS,
//                                @Value("${use.compiled.javascript:true}") boolean useCompiledJavaScript,
//                                @Value("${verify.http.timeout:1000}") int verifyHttpTimeout,
//                                @Value("${verify.executor.threads:10}") int verifyExecutorThreads) {
//         this.useCompiledCSS = useCompiledCSS;
//         this.useCompiledJavaScript = useCompiledJavaScript;
//         this.verifyHttpTimeout = verifyHttpTimeout;
//         this.verifyExecutorThreads = verifyExecutorThreads;
//         Preconditions.checkArgument(verifyHttpTimeout > 0, "verifyHttpTimeout > 0");
//         Preconditions.checkArgument(verifyExecutorThreads > 0, "verifyExecutorThreads > 0");
//     }
// 
//     public boolean isUseCompiledCSS() {
//         return useCompiledCSS;
//     }
// 
//     public boolean isUseCompiledJavaScript() {
//         return useCompiledJavaScript;
//     }
// 
//     public int getVerifyHttpTimeout() {
//         return verifyHttpTimeout;
//     }
// 
//     public int getVerifyExecutorThreads() {
//         return verifyExecutorThreads;
//     }
// }
// 
// Path: src/main/java/com/indeed/proctor/webapp/views/JsonView.java
// public class JsonView implements View {
// 
//     private static final String CONTENT_TYPE = "application/json;charset=utf-8";
// 
//     private static final ObjectWriter JSON_WRITER = Serializers.strict().writerWithDefaultPrettyPrinter();
//     private final Object data;
// 
//     public JsonView(Object data) {
//         this.data = data;
//     }
// 
//     @Override
//     public String getContentType() {
//         return CONTENT_TYPE;
//     }
// 
//     @Override
//     public void render(Map<String, ?> model,
//                        HttpServletRequest request,
//                        HttpServletResponse response) throws Exception {
//         response.setHeader("Content-Type", CONTENT_TYPE);
//         JSON_WRITER.writeValue(response.getWriter(), data);
//     }
// }


import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.indeed.proctor.common.model.TestDefinition;
import com.indeed.proctor.common.model.TestMatrixVersion;
import com.indeed.proctor.store.ProctorStore;
import com.indeed.proctor.store.Revision;
import com.indeed.proctor.store.StoreException;
import com.indeed.proctor.webapp.db.Environment;
import com.indeed.proctor.webapp.model.WebappConfiguration;
import com.indeed.proctor.webapp.views.JsonView;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.View;
import java.util.List;
package com.indeed.proctor.webapp.controllers;



@Controller
@RequestMapping({"/api/v1", "/proctor/api/v1"})
public class TestMatrixApiController extends AbstractController {

    private static final Logger LOGGER = Logger.getLogger(TestMatrixApiController.class);

    @Autowired
    public TestMatrixApiController(final WebappConfiguration configuration,
                                   @Qualifier("trunk") final ProctorStore trunkStore,
                                   @Qualifier("qa") final ProctorStore qaStore,
                                   @Qualifier("production") final ProctorStore productionStore) {
        super(configuration, trunkStore, qaStore, productionStore);
    }

    @RequestMapping(value = "/{branchOrRevision}/matrix", method = RequestMethod.GET)
    public JsonView getTestMatrix(
            @PathVariable final String branchOrRevision
    ) throws StoreException {
        final TestMatrixVersion testMatrixVersion = queryMatrixFromBranchOrRevision(branchOrRevision);
        Preconditions.checkNotNull(testMatrixVersion, String.format("Branch or revision %s not correct", branchOrRevision));
        return new JsonView(testMatrixVersion);
    }

    @RequestMapping(value = "/{branch}/matrix/history", method = RequestMethod.GET)
    public JsonView getTestMatrixHistory(
            @PathVariable final String branch,
            @RequestParam(required = false, value = "start", defaultValue = "0") final int start,
            @RequestParam(required = false, value = "limit", defaultValue = "32") final int limit
    ) throws StoreException {
// Path: src/main/java/com/indeed/proctor/webapp/db/Environment.java
// public enum Environment {
//     WORKING("trunk", 0),
//     QA("qa", 1),
//     PRODUCTION("production", 2);
// 
//     private final String name;
//     private final int precedence;
//     private Environment(final String name, final int precedence) {
//         this.name = name;
//         this.precedence = precedence;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public int getPrecedence() {
//         return precedence;
//     }
// 
//     private static final Map<String, Environment> LOOKUP = Maps.uniqueIndex(ImmutableList.copyOf(Environment.values()), Functions.toStringFunction());
//     public static Environment fromName(String name) {
//         if(name == null) {
//             return null;
//         } else {
//             return LOOKUP.get(name.toLowerCase());
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return this.getName();
//     }
// }
// 
// Path: src/main/java/com/indeed/proctor/webapp/model/WebappConfiguration.java
// @Component
// public class WebappConfiguration {
//     private final boolean useCompiledCSS;
//     private final boolean useCompiledJavaScript;
//     private final int verifyHttpTimeout;
//     private final int verifyExecutorThreads;
// 
//     @SuppressWarnings({"SpringJavaAutowiringInspection"})
//     @Autowired
//     public WebappConfiguration(@Value("${use.compiled.css:true}") boolean useCompiledCSS,
//                                @Value("${use.compiled.javascript:true}") boolean useCompiledJavaScript,
//                                @Value("${verify.http.timeout:1000}") int verifyHttpTimeout,
//                                @Value("${verify.executor.threads:10}") int verifyExecutorThreads) {
//         this.useCompiledCSS = useCompiledCSS;
//         this.useCompiledJavaScript = useCompiledJavaScript;
//         this.verifyHttpTimeout = verifyHttpTimeout;
//         this.verifyExecutorThreads = verifyExecutorThreads;
//         Preconditions.checkArgument(verifyHttpTimeout > 0, "verifyHttpTimeout > 0");
//         Preconditions.checkArgument(verifyExecutorThreads > 0, "verifyExecutorThreads > 0");
//     }
// 
//     public boolean isUseCompiledCSS() {
//         return useCompiledCSS;
//     }
// 
//     public boolean isUseCompiledJavaScript() {
//         return useCompiledJavaScript;
//     }
// 
//     public int getVerifyHttpTimeout() {
//         return verifyHttpTimeout;
//     }
// 
//     public int getVerifyExecutorThreads() {
//         return verifyExecutorThreads;
//     }
// }
// 
// Path: src/main/java/com/indeed/proctor/webapp/views/JsonView.java
// public class JsonView implements View {
// 
//     private static final String CONTENT_TYPE = "application/json;charset=utf-8";
// 
//     private static final ObjectWriter JSON_WRITER = Serializers.strict().writerWithDefaultPrettyPrinter();
//     private final Object data;
// 
//     public JsonView(Object data) {
//         this.data = data;
//     }
// 
//     @Override
//     public String getContentType() {
//         return CONTENT_TYPE;
//     }
// 
//     @Override
//     public void render(Map<String, ?> model,
//                        HttpServletRequest request,
//                        HttpServletResponse response) throws Exception {
//         response.setHeader("Content-Type", CONTENT_TYPE);
//         JSON_WRITER.writeValue(response.getWriter(), data);
//     }
// }


// Path: src/main/java/com/indeed/proctor/webapp/controllers/TestMatrixApiController.java
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.indeed.proctor.common.model.TestDefinition;
import com.indeed.proctor.common.model.TestMatrixVersion;
import com.indeed.proctor.store.ProctorStore;
import com.indeed.proctor.store.Revision;
import com.indeed.proctor.store.StoreException;
import com.indeed.proctor.webapp.db.Environment;
import com.indeed.proctor.webapp.model.WebappConfiguration;
import com.indeed.proctor.webapp.views.JsonView;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.View;
import java.util.List;

package com.indeed.proctor.webapp.controllers;



@Controller
@RequestMapping({"/api/v1", "/proctor/api/v1"})
public class TestMatrixApiController extends AbstractController {

    private static final Logger LOGGER = Logger.getLogger(TestMatrixApiController.class);

    @Autowired
    public TestMatrixApiController(final WebappConfiguration configuration,
                                   @Qualifier("trunk") final ProctorStore trunkStore,
                                   @Qualifier("qa") final ProctorStore qaStore,
                                   @Qualifier("production") final ProctorStore productionStore) {
        super(configuration, trunkStore, qaStore, productionStore);
    }

    @RequestMapping(value = "/{branchOrRevision}/matrix", method = RequestMethod.GET)
    public JsonView getTestMatrix(
            @PathVariable final String branchOrRevision
    ) throws StoreException {
        final TestMatrixVersion testMatrixVersion = queryMatrixFromBranchOrRevision(branchOrRevision);
        Preconditions.checkNotNull(testMatrixVersion, String.format("Branch or revision %s not correct", branchOrRevision));
        return new JsonView(testMatrixVersion);
    }

    @RequestMapping(value = "/{branch}/matrix/history", method = RequestMethod.GET)
    public JsonView getTestMatrixHistory(
            @PathVariable final String branch,
            @RequestParam(required = false, value = "start", defaultValue = "0") final int start,
            @RequestParam(required = false, value = "limit", defaultValue = "32") final int limit
    ) throws StoreException {
        final Environment environment = Environment.fromName(branch);