package cn.com.qmth.stmms.admin.config;

import cn.com.qmth.stmms.biz.config.model.SystemAuth;
import cn.com.qmth.stmms.biz.config.service.SystemAuthService;
import cn.com.qmth.stmms.biz.config.service.impl.SystemCache;
import cn.com.qmth.stmms.biz.school.service.SchoolService;
import cn.com.qmth.stmms.biz.utils.AppLicenseUtil;
import cn.com.qmth.stmms.biz.utils.SolarHttpUtil;
import cn.com.qmth.stmms.common.annotation.Logging;
import cn.com.qmth.stmms.common.annotation.RoleRequire;
import cn.com.qmth.stmms.common.controller.BaseController;
import cn.com.qmth.stmms.common.enums.LogType;
import cn.com.qmth.stmms.common.enums.Role;
import cn.com.qmth.stmms.common.enums.SystemAuthType;
import cn.com.qmth.stmms.common.utils.AesUtils;
import cn.com.qmth.stmms.common.utils.Encodes;

import com.qmth.boot.tools.models.ByteArray;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Date;

@Controller
@RequestMapping("/admin/sys/auth")
public class SystemAuthController extends BaseController {

    private static Logger log = LoggerFactory.getLogger(SystemAuthController.class);

    @Autowired
    private SystemAuthService authService;

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private SystemCache authCache;

    @Value("${qmth.solar.host}")
    private String host;

    @Value("${qmth.solar.app.uri}")
    private String uri;

    @Logging(menu = "查询授权信息", type = LogType.QUERY)
    @RoleRequire(Role.SYS_ADMIN)
    @RequestMapping
    public ModelAndView list(HttpServletRequest request) {
        ModelAndView view = new ModelAndView("modules/sys/authInfo");
        SystemAuth systemAuth = authService.findOne();
        view.addObject("systemAuth", systemAuth == null ? new SystemAuth() : systemAuth);
        view.addObject("typeList", SystemAuthType.values());
        view.addObject("auth", authCache.isAuth());
        view.addObject("doubleTrack", authCache.isDoubleTrack());
        view.addObject("groupDeleteWarn", authCache.isGroupDeleteWarn());
        view.addObject("expireTime", authCache.getExpireTime() == null ? null : new Date(authCache.getExpireTime()));
        return view;
    }

    @RoleRequire(Role.SYS_ADMIN)
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView edit(HttpServletRequest request) {
        ModelAndView view = new ModelAndView("modules/sys/authEdit");
        SystemAuth systemAuth = authService.findOne();
        view.addObject("systemAuth", systemAuth == null ? new SystemAuth() : systemAuth);
        view.addObject("typeList", SystemAuthType.values());
        view.addObject("auth", authCache.isAuth());
        view.addObject("expireTime", authCache.getExpireTime() == null ? null : new Date(authCache.getExpireTime()));
        return view;
    }

    @Logging(menu = "修改授权配置", type = LogType.UPDATE)
    @RoleRequire(Role.SYS_ADMIN)
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(HttpServletRequest request, RedirectAttributes redirectAttributes, SystemAuth systemAuth,
            MultipartFile file) {
        if (SystemAuthType.ONLINE.equals(systemAuth.getType())) {
            SolarHttpUtil httpUtil = new SolarHttpUtil(systemAuth.getAccessKey(), systemAuth.getAccessSecret(), host,
                    uri);
            systemAuth.setAccessKey(AesUtils.encrypt(systemAuth.getAccessKey()));
            systemAuth.setAccessSecret(AesUtils.encrypt(systemAuth.getAccessSecret()));
            authService.save(systemAuth);
            if (httpUtil.getAPP()) {
                authCache.setAuth(true);
                authCache.setDoubleTrack(true);
                authCache.setExpireTime(null);
                schoolService.updateOrg();
            } else {
                authCache.setAuth(false);
                authCache.setDoubleTrack(false);
                authCache.setExpireTime(null);
                addMessage(redirectAttributes, "授权验证失败");
            }
        } else {
            try {
                systemAuth.setDescription(ByteArray.fromInputStream(file.getInputStream()).toBase64());
                JSONObject json = AppLicenseUtil.parseLicense(ByteArray.fromInputStream(file.getInputStream()).value());
                authCache.parseJson(json);
                authService.save(systemAuth);
                if (json == null) {
                    addMessage(redirectAttributes, "授权文件解析失败");
                }
            } catch (IOException e) {
                addMessage(redirectAttributes, "授权文件解析失败");
                e.printStackTrace();
                log.error("parseLicense error", e);
            }
        }
        return "redirect:/admin/sys/auth";
    }

    @Logging(menu = "导出硬件信息", type = LogType.EXPORT)
    @RoleRequire(Role.SYS_ADMIN)
    @RequestMapping(value = "/exportInfo")
    public String exportInfo(HttpServletResponse response, RedirectAttributes redirectAttributes) {
        try {
            download(response, AppLicenseUtil.buildDeviceInfo().value());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("export device.info error", e);
        }
        return "redirect:/admin/sys/auth";
    }

    private void download(HttpServletResponse response, byte[] data) throws Exception {
        response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("device.info"));
        IOUtils.copy(new ByteArrayInputStream(data), response.getOutputStream());
    }

    protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
        StringBuilder sb = new StringBuilder();
        for (String message : messages) {
            sb.append(message).append(messages.length > 1 ? "<br/>" : "");
        }
        redirectAttributes.addFlashAttribute("message", sb.toString());
    }
}
