package com.sagacloud.utils;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.internal.OSSUtils;
import com.aliyun.oss.model.OSSObject;
import com.github.rjeschke.txtmark.Processor;
import com.sagacloud.endpoints.Doc;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

public class OssUtils {
    private static final Logger log = LoggerFactory.getLogger(OssUtils.class);
//    public static OSSClient client = new OSSClient(getProperty("oss.endpoint"), getProperty("oss.accessKeyId"), getProperty("oss.accessKeySecret"));
    public static OSSClient client = null;
    private static Properties prop = null;
    private static Map<String, String> configMap = new ConcurrentHashMap<>();

    public static void init(){
        try{
            client = new OSSClient(getProperty("oss.endpoint"), getProperty("oss.accessKeyId"), getProperty("oss.accessKeySecret"));
        } catch (Exception e){
            e.printStackTrace();
            log.error("cannot initialize OSSClient.");
        }
    }

    public static String getPropertyOld(String key){
        if(prop == null) {
            prop = new Properties();
            try {
                prop.load(OssUtils.class.getClassLoader().getResourceAsStream("config.properties"));
            } catch (IOException e) {
                e.printStackTrace();
                log.error("Load properties failed.");
            }
        }
        return prop.getProperty(key);
    }
    public static String getProperty(String key){
        if(!configMap.containsKey(key)) {
            synchronized (OSSUtils.class) {
                try {
                    if (prop == null) {
                        prop = new Properties();
                        prop.load(OssUtils.class.getClassLoader().getResourceAsStream("config.properties"));
                    }
                    if (!configMap.containsKey(key)) {
                        if(prop.getProperty(key) != null){
                            configMap.put(key, prop.getProperty(key));
                        }else{
                            log.debug("Failed to get property: " + key);
                        }
                    }
                } catch (IOException e) {
                    log.error("Load properties failed.", e);
                }
            }
        }
        return configMap.get(key);
    }
    public static String getFileAsString(String filePath)throws Exception{
        if(getProperty("dict.source").equals("oss"))
            return getOssFileAsString(filePath);
        else if(getProperty("dict.source").equals("local")){
            return getLocalFileAsString(filePath);
        }
        throw new Exception("配置中没有指定数据字典的数据源!");
    }

    private static String getLocalFileAsString(String filePath) {
        String docContentStr = null;
        try {
            docContentStr = IOUtils.toString(OssUtils.class.getClassLoader().getResourceAsStream(filePath), StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.info(String.join("",  filePath, "出错!"));
            //e.printStackTrace();
        }
        return docContentStr;
    }

    public static String getOssFileAsString(String filePath) throws Exception {
        OSSObject ossObject = null;
        InputStream inputStream = null;
        try {
            ossObject = OssUtils.client.getObject(OssUtils.getProperty("oss.bucketName"),
                    String.join("/", OssUtils.getProperty("oss.basePath"), filePath));
//            ClientConfiguration cf = OssUtils.client.getClientConfiguration();
//            cf.setSLDEnabled(true);
            inputStream = ossObject.getObjectContent();
            return IOUtils.toString(inputStream);
        }catch (Exception e){
            throw e;
        }finally {
            try {
                if (inputStream != null)
                    inputStream.close();
            }catch (Exception ignore) {}
            try {
                if (ossObject != null)
                    ossObject.close();
            }catch (Exception ignore) {}
        }
    }
}
