package com.bonus.canteen.core.config;

import com.google.common.collect.Maps;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Optional;

public class WebContext {
   private static final ThreadLocal<Context> THREAD_CONTEXT = new InheritableThreadLocal<Context>() {
      protected Context initialValue() {
         return new Context();
      }
   };

   private WebContext() {
   }

   public static void reset() {
      THREAD_CONTEXT.remove();
   }

   public static Context get() {
      return (Context)THREAD_CONTEXT.get();
   }

   public static void set(Context context) {
      THREAD_CONTEXT.set(context);
   }

   public static class Context {
      private HttpServletRequest request;
      private HttpServletResponse response;
      private AccessToken accessToken;
      private Map<String, Object> attributes = Maps.newHashMap();

      public Context(HttpServletRequest request, HttpServletResponse response) {
         this.request = request;
         this.response = response;
      }

      public void setAttribute(String key, Object data) {
         this.attributes.put(key, data);
      }

      public Object getAttribute(String key) {
         return this.attributes.get(key);
      }

      public void removeAttribute(String key) {
         this.attributes.remove(key);
      }

      public void clearAttribute() {
         this.attributes.clear();
      }

      public Optional<AccessToken> getAccessToken() {
         return Optional.ofNullable(this.accessToken);
      }

      public Optional<HttpServletRequest> getRequest() {
         return Optional.ofNullable(this.request);
      }

      public Optional<HttpServletResponse> getResponse() {
         return Optional.ofNullable(this.response);
      }

      public Map<String, Object> getAttributes() {
         return this.attributes;
      }

      public void setRequest(final HttpServletRequest request) {
         this.request = request;
      }

      public void setResponse(final HttpServletResponse response) {
         this.response = response;
      }

      public void setAccessToken(final AccessToken accessToken) {
         this.accessToken = accessToken;
      }

      public void setAttributes(final Map<String, Object> attributes) {
         this.attributes = attributes;
      }

      public Context() {
      }

      public Context(final HttpServletRequest request, final HttpServletResponse response, final AccessToken accessToken, final Map<String, Object> attributes) {
         this.request = request;
         this.response = response;
         this.accessToken = accessToken;
         this.attributes = attributes;
      }
   }
}
