package com.qmth.ops.aliyun.utils;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.qmth.ops.aliyun.config.SlsConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

@Component
public class SlsService {

    private List<SlsProject> projectList;

    @Autowired
    private SlsConfig config;

    @Value("${ops.host}")
    private String hostUrl;

    public List<SlsProject> getProject() {
        return projectList;
    }

    public Mono<String> view(String project, String store) {
        AssumeRoleResponse response = AssumeRoleClient.get(config);
        Mono<String> token = getToken(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(),
                response.getCredentials().getSecurityToken());
        return getSignUrl(token, project, store);
    }

    private Mono<String> getToken(String accessKey, String accessSecret, String token) {
        return WebClient.create().get().uri(config.getTokenUrl(), accessKey, accessSecret, token).retrieve().bodyToMono(String.class)
                .flatMap(body -> {
                    JSONObject json = JSONObject.parseObject(body);
                    String st = json.getString("SigninToken");
                    return st != null ? Mono.just(st) : Mono.error(new RuntimeException("get SigninToken faile: " + body));
                });
    }

    private Mono<String> getSignUrl(Mono<String> token, String project, String store) {
        return token.flatMap(t -> Mono.just(MessageFormat
                .format(config.getSignUrl(), param(hostUrl), param(MessageFormat.format(config.getQueryUrl(), project, store)), param(t))));
    }

    private static String param(String content) {
        try {
            return URLEncoder.encode(content, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }

    @PostConstruct
    public void initProject() throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(new ClassPathResource("sls-project.txt").getInputStream()));
        projectList = new ArrayList<>();
        String line = null;
        while ((line = reader.readLine()) != null) {
            String[] values = line.split(",");
            SlsProject project = new SlsProject();
            project.setGroup(values[0]);
            project.setName(values[1]);
            project.setProject(values[2]);
            project.setStore(values[3]);
            projectList.add(project);
        }
        reader.close();
    }
}
