package org.exoplatform.cs.portlet.environment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.inject.Inject;

import juzu.HttpMethod;
import juzu.MimeType;
import juzu.Path;
import juzu.Resource;
import juzu.Response;
import juzu.SessionScoped;
import juzu.View;
import juzu.plugin.jackson.Jackson;
import juzu.template.Template;

import org.exoplatform.commons.juzu.ajax.Ajax;
import org.exoplatform.cs.dto.EnvironmentDTO;
import org.exoplatform.cs.dto.TypeDTO;
import org.exoplatform.cs.entity.ASTypeEntity;
import org.exoplatform.cs.entity.DBTypeEntity;
import org.exoplatform.cs.entity.EnvTypeEntity;
import org.exoplatform.cs.entity.JVMTypeEntity;
import org.exoplatform.cs.entity.OSTypeEntity;
import org.exoplatform.cs.entity.SSOTypeEntity;
import org.exoplatform.cs.portlet.common.CSControllerBase;
import org.exoplatform.cs.service.EnvironmentService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;

@SessionScoped
public class EnvironmentController extends CSControllerBase {
  private static Log log = ExoLogger.getLogger(EnvironmentController.class);

  @Inject
  EnvironmentService environmentService;

  @Inject
  @Path("index.gtmpl")
  Template           indexTmpl;

  @View
  public Response.Content index() {
    return indexTmpl.ok();
  }

  @Ajax
  @Resource
  @MimeType.JSON
  @Jackson
  public List<EnvironmentDTO> getEnvironments() {
    List<EnvironmentDTO> environments = new ArrayList<>();
    try {
      String spaceGroupId = getCurrentSpaceId();
      environments = environmentService.getSpaceEnvironments(spaceGroupId);
    } catch (Exception e) {
      log.error(e);
    }
    return environments;
  }
  
  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public List<EnvironmentDTO> saveEnvironment(@Jackson EnvironmentDTO envDTO) throws Exception {
    try {
      if (envDTO.getSpaceGroupId() == null) {
        envDTO.setSpaceGroupId(getCurrentSpaceId());
      }
      environmentService.saveEnvironment(envDTO);
      return getEnvironments();
    } catch (Exception e) {
      log.error("Error while saving environment: " + envDTO, e);
      throw e;
    }
  }

  @Resource
  @Ajax
  @MimeType.JSON
  @Jackson
  public Map<String, List<TypeDTO>> getTypes() throws Exception {
    Map<String, List<TypeDTO>> types = new HashMap<String, List<TypeDTO>>();
    types.put(JVMTypeEntity.TYPE_NAME, environmentService.getTypeObjects(JVMTypeEntity.TYPE_NAME));
    types.put(OSTypeEntity.TYPE_NAME, environmentService.getTypeObjects(OSTypeEntity.TYPE_NAME));
    types.put(ASTypeEntity.TYPE_NAME, environmentService.getTypeObjects(ASTypeEntity.TYPE_NAME));
    types.put(SSOTypeEntity.TYPE_NAME, environmentService.getTypeObjects(SSOTypeEntity.TYPE_NAME));
    types.put(DBTypeEntity.TYPE_NAME, environmentService.getTypeObjects(DBTypeEntity.TYPE_NAME));
    types.put(EnvTypeEntity.TYPE_NAME, environmentService.getTypeObjects(EnvTypeEntity.TYPE_NAME));
    return types;
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public void saveType(@Jackson TypeDTO typeDTO) throws Exception {
    try {
      environmentService.saveType(typeDTO);
    } catch (Exception e) {
      log.error(e);
      throw e;
    }
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public void deleteType(@Jackson TypeDTO typeDTO) throws Exception {
    try {
      environmentService.removeType(typeDTO);
    } catch (Exception e) {
      log.error(e);
      throw e;
    }
  }

  @Ajax
  @Resource(method = HttpMethod.POST)
  @MimeType.JSON
  @Jackson
  public List<EnvironmentDTO> deleteEnvironment(@Jackson EnvironmentDTO envDTO) {
    try {
      environmentService.remove(envDTO);
      return getEnvironments();
    } catch (Exception e) {
      log.error(e);
      throw e;
    }
  }

  @Ajax
  @juzu.Resource
  @MimeType.JSON
  @Jackson
  public Response getBundle(String locale) {
    return super.getBundle(new Locale(locale));
  }

  @Override
  public Log getLogger() {
    return log;
  }
}
