package org.ambraproject.wombat.controller;

import com.google.common.collect.ImmutableMap;
import org.ambraproject.wombat.config.site.RequestMappingContextDictionary;
import org.ambraproject.wombat.config.site.Site;
import org.ambraproject.wombat.config.site.SiteParam;
import org.ambraproject.wombat.config.site.url.Link;
import org.ambraproject.wombat.model.ScholarlyWorkId;
import org.ambraproject.wombat.service.ApiAddress;
import org.ambraproject.wombat.service.remote.ArticleApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

@Controller
public class ScholarlyWorkController {

  @Autowired
  private ArticleApi articleApi;
  @Autowired
  private RequestMappingContextDictionary requestMappingContextDictionary;

  @RequestMapping(name = "work", value = "/work")
  public String redirectToWork(HttpServletRequest request,
                               @SiteParam Site site,
                               ScholarlyWorkId workId)
      throws IOException {
    return getRedirectFor(site, workId).get(request);
  }

  private String getTypeOf(ScholarlyWorkId workId) throws IOException {
    Map<String, Object> workMetadata = articleApi.requestObject(workId.appendId(ApiAddress.builder("work")), Map.class);
    return (String) workMetadata.get("type");
  }

  private static final ImmutableMap<String, String> REDIRECT_HANDLERS = ImmutableMap.<String, String>builder()
      .put("article", "article")
      .put("figure", "figurePage")
      .put("table", "figurePage")
          // TODO: supp info
      .build();

  private Link getRedirectFor(Site site, ScholarlyWorkId workId) throws IOException {
    String handlerName = REDIRECT_HANDLERS.get(getTypeOf(workId));
    if (handlerName == null) {
      throw new RuntimeException("Unrecognized type: " + workId);
    }
    Link.Factory.PatternBuilder handlerLink = Link.toLocalSite(site)
        .toPattern(requestMappingContextDictionary, handlerName);
    return pointLinkToWork(handlerLink, workId);
  }

  private static Link pointLinkToWork(Link.Factory.PatternBuilder link, ScholarlyWorkId workId) {
    link.addQueryParameter("id", workId.getDoi());
    workId.getRevisionNumber().ifPresent(revisionNumber ->
        link.addQueryParameter("rev", revisionNumber));
    return link.build();
  }

  @RequestMapping(name = "work", value = "/work")
  public void redirectToWorkFile(HttpServletRequest request,
                                 @SiteParam Site site,
                                 ScholarlyWorkId workId,
                                 @RequestParam("fileType") String fileType)
      throws IOException {
    // TODO
  }

}

@@ -422,16 +422,80 @@
 ddress;%0A
+import org.ambraproject.wombat.service.EntityNotFoundException;%0A
 import o
@@ -1353,16 +1353,24 @@
 kId).get
+Redirect
 (request
@@ -1391,24 +1391,43 @@
 ate 
+Map%3C
 String
- getTypeOf
+, Object%3E getWorkMetadata
 (Sch
@@ -1476,124 +1476,342 @@
     
-Map%3CString, Object%3E workMetadata = articleApi.requestObject(workId.appendId(ApiAddress.builder(%22work%22)), Map.class);
+ApiAddress address = workId.appendId(ApiAddress.builder(%22work%22));%0A    try %7B%0A      return articleApi.requestObject(address, Map.class);%0A    %7D catch (EntityNotFoundException e) %7B%0A      throw new NotFoundException(%22No work exists with ID: %22 + workId, e);%0A    %7D%0A  %7D%0A%0A  private String getTypeOf(ScholarlyWorkId workId) throws IOException %7B
 %0A   
@@ -1827,17 +1827,20 @@
 String) 
-w
+getW
 orkMetad
@@ -1842,16 +1842,24 @@
 Metadata
+(workId)
 .get(%22ty
@@ -2889,32 +2889,36 @@
 ing(name = %22work
+File
 %22, value = %22/wor
@@ -2911,32 +2911,55 @@
  value = %22/work%22
+, params = %7B%22fileType%22%7D
 )%0A  public void 

Debug ScholarlyWorkController