package com.bsmlab.dfx.agent;

import com.bsmlab.dfx.agent.config.AgentConfigDto;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

@SpringBootApplication
public class DfxAgentApplication {

	public static void main(String[] args) {
        //--setting.file=$AGENT_HOME/conf/settings.json --setting.check
        // --parse.message.file
        boolean hasSettingFile = false;
        boolean hasSettingCheck = false;
        boolean hasParseMessageFile = false;
        String settingFilePath = null;
        if(args != null) {
            for(String arg : args) {
                if(arg != null && arg.contains("setting.file")) {
                    if(arg.split("=").length == 2) {
                        settingFilePath = arg.split("=")[1].trim();
                        if(Files.exists(Path.of(settingFilePath))) {
                            hasSettingFile = true;
                        }
                    }
                }
                if(arg != null && arg.contains("setting.check")) {
                    hasSettingCheck = true;
                }
                if(arg != null && arg.contains("parse.message.file")) {
                    hasParseMessageFile = true;
                }
            }
        }
        if(hasSettingFile && !hasSettingCheck && !hasParseMessageFile) {
            Map<String, Object> props = new HashMap<>();
            boolean isCorrect = true;
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                AgentConfigDto agentConfigDto = objectMapper.readValue(new File(settingFilePath), AgentConfigDto.class);
                if(agentConfigDto.isSslEnabled()) {
                    props.put("server.port", agentConfigDto.getMyListenPort());
                    props.put("server.ssl.enabled", agentConfigDto.isSslEnabled());
                    props.put("server.ssl.key-store", System.getProperty("javax.net.ssl.keyStore"));
                    String keyStoreFilePath = String.valueOf(props.get("server.ssl.key-store"));
                    if(keyStoreFilePath.startsWith("file:/")) {
                        keyStoreFilePath = keyStoreFilePath.substring(6);
                    }
                    File keyStoreFile = new File(keyStoreFilePath);
                    if(!keyStoreFile.exists()) {
                        System.out.println("cannot find a keystore file: " + keyStoreFilePath);
                        System.exit(0);
                    }
                    props.put("server.ssl.key-store-password", System.getProperty("javax.net.ssl.keyStorePassword"));
                    props.put("server.ssl.key-store-type", System.getProperty("javax.net.ssl.keyStoreType"));
                    props.put("server.ssl.trust-store", System.getProperty("javax.net.ssl.trustStore"));
                    String trustStoreFilePath = String.valueOf(props.get("server.ssl.trust-store"));
                    if(trustStoreFilePath.startsWith("file:/")) {
                        trustStoreFilePath = trustStoreFilePath.substring(6);
                    }
                    File trustStoreFile = new File(trustStoreFilePath);
                    if(!trustStoreFile.exists()) {
                        System.out.println("cannot find a truststore file: " + trustStoreFilePath);
                        System.exit(0);
                    }
                    props.put("server.ssl.trust-store-password", System.getProperty("javax.net.ssl.trustStorePassword"));
                    props.put("server.ssl.trust-store-type", "JKS");
                    props.put("server.ssl.client-auth", "need");
                }
            } catch (DatabindException e) {
                System.out.println("cannot parse a setting file. " + settingFilePath);
                e.printStackTrace(System.out);
                isCorrect = false;
            } catch (IOException e) {
                System.out.println("cannot read a setting file. " + settingFilePath);
                e.printStackTrace(System.out);
                isCorrect = false;
            }
            if(isCorrect) {
                SpringApplication springApplication = new SpringApplication(DfxAgentApplication.class);
                if(!props.isEmpty()) {
                    springApplication.setDefaultProperties(props);
                }
                springApplication.run(args);
            }
        }
	}

}
