package com.tofly.auth.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.tofly.common.core.constant.CommonConstants;
import com.tofly.common.core.constant.SecurityConstants;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.log.annotation.ToFlyAppLog;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/oauth")
@Api(tags = "登陆接口")
@Slf4j
public class OauthController {
    @Autowired
    private TokenEndpoint tokenEndpoint;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ValueOperations<String, String> valueOperations;

    /* @Value("${security.oauth2.tokenExpireTime}")*/
    private Long tokenExpireTime = 3600 * 24L;
    private final Long SUCCESS = 1L;

    @GetMapping("/token")
    public ResultRespone getAccessToken(Principal principal, @ApiParam(hidden = true) @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        return custom(tokenEndpoint.getAccessToken(principal, parameters).getBody());
    }

    @PostMapping("/token")
    @ApiOperation(value = "使用post方式登陆")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String")
    })
    public ResultRespone postAccessToken(@ApiParam(hidden = true) Principal principal, @ApiParam(hidden = true) @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        return custom(tokenEndpoint.postAccessToken(principal, parameters).getBody());
    }

    /**
     * @deprecated 未使用, gateway处修改为/token,
     */
    @PostMapping("/login")
    @ApiOperation(value = "使用post方式登陆")
    @ApiImplicitParams({    
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String")
    })
    @ToFlyAppLog(title = "登录", type = CommonConstants.LOG_LOGIN)
    public ResultRespone login() throws HttpRequestMethodNotSupportedException {
        return null;
    }

    //自定义返回格式
    private ResultRespone custom(OAuth2AccessToken accessToken) {
        DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken;

        Map<String, Object> data = new LinkedHashMap(token.getAdditionalInformation());

        String tokenValue = token.getValue();
        data.put("accessToken", token.getValue());
        data.put("expiresIn", token.getExpiresIn());
        if (token.getRefreshToken() != null) {
            data.put("refreshToken", token.getRefreshToken().getValue());
        }

        String o = valueOperations.get(SecurityConstants.REDIS_LOGIN_LOCK);
        String username = (String) data.get("username");
        log.info("当前用户为：{}, 获取project为:{}, token为：{}", username, o, tokenValue);

        if (!StringUtil.isEmpty(o)) {
            valueOperations.getOperations().delete(SecurityConstants.REDIS_LOGIN_LOCK);
            valueOperations.set(tokenValue, o);
        }
        // token设置超时时间3600
        String s = "tofly_oauth:auth:" + tokenValue;
        redisTemplate.expire(s, tokenExpireTime, TimeUnit.SECONDS);
        // 设置一个回调Key,失效删除
        redisTemplate.opsForValue().set(s + "_2", username);
        Long expire = redisTemplate.opsForValue().getOperations().getExpire(s);

        log.info("当前用户为token设置失效时长为：{}", expire);
        return ResultRespone.success(data);
    }

}
