/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.hadoop.yarn.webapp;

import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.servlet.RequestScoped;

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.apache.hadoop.yarn.util.StringHelper.*;

import org.apache.hadoop.yarn.webapp.view.DefaultPage;

import org.codehaus.jackson.map.ObjectMapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class Controller implements Params {
  public static final Logger LOG = LoggerFactory.getLogger(Controller.class);
  static final ObjectMapper jsonMapper = new ObjectMapper();

  @RequestScoped
  public static class RequestContext{
    final Injector injector;
    final HttpServletRequest request;
    final HttpServletResponse response;
    private Map<String, String> moreParams;
    private Map<String, Cookie> cookies;
    int status = 200; // pre 3.0 servlet-api doesn't have getStatus
    boolean rendered = false;
    Throwable error;
    boolean devMode = false;
    String prefix;

    @Inject RequestContext(Injector injector, HttpServletRequest request,
                           HttpServletResponse response) {
      this.injector = injector;
      this.request = request;
      this.response = response;
    }

    public int status() { return status; }

    public void setStatus(int status) {
      this.status = status;
      response.setStatus(status);
    }

    public void setRendered(boolean rendered) {
      this.rendered = rendered;
    }

    public Map<String, String> moreParams() {
      if (moreParams == null) {
        moreParams = Maps.newHashMap();
      }
      return moreParams; // OK
    }

    public Map<String, Cookie> cookies() {
      if (cookies == null) {
        cookies = Maps.newHashMap();
        Cookie[] rcookies = request.getCookies();
        if (rcookies != null) {
          for (Cookie cookie : rcookies) {
            cookies.put(cookie.getName(), cookie);
          }
        }
      }
      return cookies; // OK
    }

    public void set(String key, String value) {
      moreParams().put(key, value);
    }

    public String get(String key, String defaultValue) {
      String value = moreParams().get(key);
      if (value == null) {
        value = request.getParameter(key);
      }
      return value == null ? defaultValue : value;
    }

    public String prefix() { return prefix; }
  }

  private RequestContext context;
  @Inject Injector injector;

  public Controller() {
    // Makes injection in subclasses optional.
    // Time will tell if this buy us more than the NPEs :)
  }

  public Controller(RequestContext ctx) {
    context = ctx;
  }

  public RequestContext context() {
    if (context == null) {
      if (injector == null) {
        // One of the downsides of making injection in subclasses optional.
        throw new WebAppException(join("Error accessing RequestContext from\n",
            "a child constructor, either move the usage of the Controller\n",
            "methods out of the constructor or inject the RequestContext\n",
            "into the constructor"));
      }
      context = injector.getInstance(RequestContext.class);
    }
    return context;
  }

  public Throwable error() { return context().error; }

  public int status() { return context().status; }

  public void setStatus(int status) {
    context().setStatus(status);
  }

  public boolean inDevMode() { return context().devMode; }

  public Injector injector() { return context().injector; }

  public <T> T getInstance(Class<T> cls) {
    return injector.getInstance(cls);
  }

  public HttpServletRequest request() { return context().request; }

  public HttpServletResponse response() { return context().response; }

  public void set(String key, String value) {
    context().set(key, value);
  }

  public String get(String key, String defaultValue) {
    return context().get(key, defaultValue);
  }

  public String $(String key) {
    return get(key, "");
  }

  public void setTitle(String title) {
    set(TITLE, title);
  }

  public void setTitle(String title, String url) {
    setTitle(title);
    set(TITLE_LINK, url);
  }

  public ResponseInfo info(String about) {
    return getInstance(ResponseInfo.class).about(about);
  }

  /**
   * Get the cookies
   * @return the cookies map
   */
  public Map<String, Cookie> cookies() {
    return context().cookies();
  }

 /**
   * Create an url from url components
   * @param parts components to join
   * @return an url string
   */
  public String url(String... parts) {
    return ujoin(context().prefix, parts);
  }

  /**
   * The default action.
   */
  public abstract void index();

  public void echo() {
    render(DefaultPage.class);
  }

  protected void render(Class<? extends View> cls) {
    context().rendered = true;
    getInstance(cls).render();
  }

  /**
   * Convenience method for REST APIs (without explicit views)
   * @param object - the object as the response (in JSON)
   */
  protected void renderJSON(Object object) {
    LOG.debug("{}: {}", MimeType.JSON, object);
    context().rendered = true;
    context().response.setContentType(MimeType.JSON);
    try {
      jsonMapper.writeValue(writer(), object);
    } catch (Exception e) {
      throw new WebAppException(e);
    }
  }

  protected void renderJSON(Class<? extends ToJSON> cls) {
    context().rendered = true;
    response().setContentType(MimeType.JSON);
    getInstance(cls).toJSON(writer());
  }

  /**
   * Convenience method for hello world :)
   * @param s - the content to render as plain text
   */
  protected void renderText(String s) {
    LOG.debug("{}: {}", MimeType.TEXT, s);
    context().rendered = true;
    response().setContentType(MimeType.TEXT);
    writer().print(s);
  }

  protected PrintWriter writer() {
    try {
      return response().getWriter();
    } catch (Exception e) {
      throw new WebAppException(e);
    }
  }
}
