/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)

Licensed 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 com.sf.apijson.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.sf.apijson.config.BuildApijsonAccessConfig;
import com.sf.common.annotation.Log;
import com.sf.common.core.domain.AjaxResult;
import com.sf.common.enums.BusinessType;
import com.sf.framework.web.service.PermissionService;
import com.sf.generator.domain.GenTable;
import com.sf.generator.service.IGenTableService;

import apijson.JSON;
import apijson.JSONObject;
import apijson.RequestMethod;
import apijson.orm.Parser;
import apijson.router.APIJSONRouterController;

/**
 * 提供入口，转交给 APIJSON 的 Parser 来处理
 * 
 * @author Lemon
 */
@RestController
@RequestMapping("/forms/api")
public class FormController extends APIJSONRouterController<String> {
	@Autowired
	private IGenTableService genTableService;

	@Autowired
	private PermissionService permissionService;

	@Override
	public Parser<String> newParser(HttpSession session, RequestMethod method) {
		return super.newParser(session, method).setNeedVerify(true).setNeedVerifyLogin(true); // TODO //
																								// 这里关闭校验，方便新手快速测试，实际线上项目建议开启
	}

	@PostMapping("router/{method}/{tag}")
	@Override
	public String router(@PathVariable String method, @PathVariable String tag,
			@RequestParam Map<String, String> params, @RequestBody String request, HttpSession session) {
		String perm = "router:" + method + ":" + tag; // 权限标识
		if (permissionService.hasPermi(perm) == false) {
			// 仅具有ROLE_ADMIN权限的用户可访问的逻辑
			return JSON.toJSONString(AjaxResult.error("对不起，您没有接口访问权限!"));
		}
		return super.router(method, tag, params, request, session);
	}

	/**
	 * 获取
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#GET}
	 */
	@PostMapping(value = "get")
	@Override
	public String get(@RequestBody String request, HttpSession session) {
		return super.get(request, session);
	}

	/**
	 * 计数
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#HEAD}
	 */
	@PostMapping("head")
	@Override
	public String head(@RequestBody String request, HttpSession session) {
		return super.head(request, session);
	}

	/**
	 * 限制性GET，request和response都非明文，浏览器看不到，用于对安全性要求高的GET请求
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#GETS}
	 */
	@PostMapping("gets")
	@Override
	public String gets(@RequestBody String request, HttpSession session) {
		return super.gets(request, session);
	}

	/**
	 * 限制性HEAD，request和response都非明文，浏览器看不到，用于对安全性要求高的HEAD请求
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#HEADS}
	 */
	@PostMapping("heads")
	@Override
	public String heads(@RequestBody String request, HttpSession session) {
		return super.heads(request, session);
	}

	/**
	 * 新增
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#POST}
	 */
	@PostMapping("post")
	@Override
	public String post(@RequestBody String request, HttpSession session) {
		return super.post(request, session);
	}

	/**
	 * 修改
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#PUT}
	 */
	@PostMapping("put")
	@Override
	public String put(@RequestBody String request, HttpSession session) {
		return super.put(request, session);
	}

	/**
	 * 删除
	 * 
	 * @param request 只用String，避免encode后未decode
	 * @param session
	 * @return
	 * @see {@link RequestMethod#DELETE}
	 */
	@PostMapping("delete")
	@Override
	public String delete(@RequestBody String request, HttpSession session) {
		return super.delete(request, session);
	}

	@PostMapping("crud")
	@Override
	public String crud(@RequestBody String request, HttpSession session) {
		return super.crud(request, session);
	}

	/**
	 * 表生成APIJSON配置
	 */
	@Log(title = "表生成APIJSON配置", businessType = BusinessType.GENCODE)
	@PreAuthorize("@ss.hasPermi('apijson:tool:gen')")
	@PostMapping("/genCode/{tableId}")
	public String genCode(@PathVariable("tableId") Long tableId, HttpSession session) throws Exception {
		GenTable table = genTableService.getGeneratorTable(tableId);
		String urlSuffix = (char) (int) (Math.random() * 26 + 65) + String.valueOf(System.currentTimeMillis());
		return BuildApijsonAccessConfig.generatorJsonCode(table, urlSuffix, session).toJSONString();
	}

	@Log(title = "生成Function url", businessType = BusinessType.GENCODE)
	@PreAuthorize("@ss.hasPermi('apijson:tool:gen:functions')")
	@PostMapping("/genCode/functions")
	public String generatorCodeFunction(@NotNull @RequestBody String request, HttpSession session) throws Exception {
		return JSON.toJSONString(BuildApijsonAccessConfig.generatorCodeFunction(request, session));
	}

	@Log(title = "生成json url", businessType = BusinessType.GENCODE)
	@PreAuthorize("@ss.hasPermi('apijson:tool:gen:json')")
	@PostMapping("/genCode/json")
	public String generatorCodeJSON(@NotNull @RequestBody String request, HttpSession session) throws Exception {
		return JSON.toJSONString(BuildApijsonAccessConfig.generatorCodeJSON(request, session));
	}

	// 列表
	@GetMapping("/gen/{tag}/list")
	public String list(@PathVariable String tag, @RequestParam Map<String, String> params, HttpSession session) {
		return super.router(RequestMethod.GET.toString().toLowerCase(), tag+"list", params, null, session);
	}

	// 新增
	@PostMapping("/gen/{tag}")
	public String save(@PathVariable String tag, @RequestParam Map<String, String> params, @RequestBody String request,
			HttpSession session) {
		return super.router(RequestMethod.POST.toString().toLowerCase(), tag, params, request, session);
	}

	// 修改
	@PutMapping("/gen/{tag}")
	public String update(@PathVariable String tag, @RequestParam Map<String, String> params,
			@RequestBody String request, HttpSession session) {
		return super.router(RequestMethod.PUT.toString().toLowerCase(), tag, params, request, session);
	}

	// 详情
	@GetMapping("/gen/{tag}/{id}")
	public String detail(@PathVariable String tag, @PathVariable String id, HttpSession session) {
		Map<String, String> params = new HashMap<>();
		params.put("id", id);
		return super.router(RequestMethod.GET.toString().toLowerCase(), tag, params, null, session);
	}

	// 删除
	@DeleteMapping("/gen/{tag}/{ids}")
	public String delete(@PathVariable String tag, @PathVariable Object ids, HttpSession session) {
		Object[] idArray = ids.toString().split(",");
        JSONObject request = new JSONObject();
        request.put("ids", idArray);
		return super.router(RequestMethod.DELETE.toString().toLowerCase(), tag, null, request.toJSONString(), session);
	}
}