// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.doris.common;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.FileReader;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConfigBase {
    private static final Logger LOG = LogManager.getLogger(ConfigBase.class);
    
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface ConfField {
        String value() default "";
        boolean mutable() default false;
        boolean masterOnly() default false;
        String comment() default "";
    }   
    
    public static Properties props;
    public static Class<? extends ConfigBase> confClass;
    
    public void init(String propfile) throws Exception {
        props = new Properties();
        confClass = this.getClass();
        props.load(new FileReader(propfile));
        replacedByEnv();
        setFields();
    }
    
    public static HashMap<String, String> dump() throws Exception { 
        HashMap<String, String> map = new HashMap<String, String>();
        Field[] fields = confClass.getFields();     
        for (Field f : fields) {
            if (f.getAnnotation(ConfField.class) == null) {
                continue;
            }
            if (f.getType().isArray()) {
                switch (f.getType().getSimpleName()) {
                    case "short[]":
                        map.put(f.getName(), Arrays.toString((short[]) f.get(null)));
                        break;
                    case "int[]":
                        map.put(f.getName(), Arrays.toString((int[]) f.get(null)));
                        break;
                    case "long[]":
                        map.put(f.getName(), Arrays.toString((long[]) f.get(null)));
                        break;
                    case "double[]":
                        map.put(f.getName(), Arrays.toString((double[]) f.get(null)));
                        break;
                    case "boolean[]":
                        map.put(f.getName(), Arrays.toString((boolean[]) f.get(null)));
                        break;
                    case "String[]":
                        map.put(f.getName(), Arrays.toString((String[]) f.get(null)));
                        break;
                    default:
                        throw new Exception("unknown type: " + f.getType().getSimpleName());
                }               
            } else {
                map.put(f.getName(), f.get(null).toString());
            }
        }
        return map;
    }
    
    private static void replacedByEnv() throws Exception {
        Pattern pattern = Pattern.compile("\\$\\{([^\\}]*)\\}");    
        for (String key : props.stringPropertyNames()) {
            String value = props.getProperty(key);
            Matcher m = pattern.matcher(value);
            while (m.find()) {
                String envValue = System.getProperty(m.group(1));
                envValue = (envValue != null) ? envValue : System.getenv(m.group(1));
                if (envValue != null) {
                    value = value.replace("${" + m.group(1) + "}", envValue);
                } else {
                    throw new Exception("no such env variable: " + m.group(1));
                }
            }
            props.setProperty(key, value);      
        }
    }
    
    private static void setFields() throws Exception {      
        Field[] fields = confClass.getFields();     
        for (Field f : fields) {
            // ensure that field has "@ConfField" annotation
            ConfField anno = f.getAnnotation(ConfField.class);
            if (anno == null) {
                continue;
            }
            
            // ensure that field has property string
            String confKey = anno.value().equals("") ? f.getName() : anno.value();
            String confVal = props.getProperty(confKey);
            if (Strings.isNullOrEmpty(confVal)) {
                continue;
            }
            
            setConfigField(f, confVal);
        }       
    }

    public static void setConfigField(Field f, String confVal) throws IllegalAccessException, Exception {
        confVal = confVal.trim();

        String[] sa = confVal.split(",");
        for (int i = 0; i < sa.length; i++) {
            sa[i] = sa[i].trim();
        }

        // set config field
        switch (f.getType().getSimpleName()) {
            case "short":
                f.setShort(null, Short.parseShort(confVal));
                break;
            case "int":
                f.setInt(null, Integer.parseInt(confVal));
                break;
            case "long":
                f.setLong(null, Long.parseLong(confVal));
                break;
            case "double":
                f.setDouble(null, Double.parseDouble(confVal));
                break;
            case "boolean":
                f.setBoolean(null, Boolean.parseBoolean(confVal));
                break;
            case "String":
                f.set(null, confVal);
                break;
            case "short[]":
                short[] sha = new short[sa.length];
                for (int i = 0; i < sha.length; i++) {
                    sha[i] = Short.parseShort(sa[i]);
                }
                f.set(null, sha);
                break;
            case "int[]":
                int[] ia = new int[sa.length];
                for (int i = 0; i < ia.length; i++) {
                    ia[i] = Integer.parseInt(sa[i]);
                }
                f.set(null, ia);
                break;
            case "long[]":
                long[] la = new long[sa.length];
                for (int i = 0; i < la.length; i++) {
                    la[i] = Long.parseLong(sa[i]);
                }
                f.set(null, la);
                break;
            case "double[]":
                double[] da = new double[sa.length];
                for (int i = 0; i < da.length; i++) {
                    da[i] = Double.parseDouble(sa[i]);
                }
                f.set(null, da);
                break;
            case "boolean[]":
                boolean[] ba = new boolean[sa.length];
                for (int i = 0; i < ba.length; i++) {
                    ba[i] = Boolean.parseBoolean(sa[i]);
                }
                f.set(null, ba);
                break;
            case "String[]":
                f.set(null, sa);
                break;
            default:
                throw new Exception("unknown type: " + f.getType().getSimpleName());
        }
    }

    public static Map<String, Field> getAllMutableConfigs() {
        Map<String, Field> mutableConfigs = Maps.newHashMap();
        Field fields[] = ConfigBase.confClass.getFields();
        for (Field field : fields) {
            ConfField confField = field.getAnnotation(ConfField.class);
            if (confField == null) {
                continue;
            }
            if (!confField.mutable()) {
                continue;
            }
            mutableConfigs.put(confField.value().equals("") ? field.getName() : confField.value(), field);
        }

        return mutableConfigs;
    }

    public synchronized static void setMutableConfig(String key, String value) throws DdlException {
        Map<String, Field> mutableConfigs = getAllMutableConfigs();
        Field field = mutableConfigs.get(key);
        if (field == null) {
            throw new DdlException("Config '" + key + "' does not exist or is not mutable");
        }

        try {
            ConfigBase.setConfigField(field, value);
        } catch (Exception e) {
            throw new DdlException("Failed to set config '" + key + "'. err: " + e.getMessage());
        }
        
        LOG.info("set config {} to {}", key, value);
    }

    public synchronized static List<List<String>> getConfigInfo() throws DdlException {
        List<List<String>> configs = Lists.newArrayList();
        Field[] fields = confClass.getFields();
        for (Field f : fields) {
            List<String> config = Lists.newArrayList();
            ConfField anno = f.getAnnotation(ConfField.class);
            if (anno == null) {
                continue;
            }

            String confKey = anno.value().equals("") ? f.getName() : anno.value();
            String confVal;
            try {
                confVal = String.valueOf(f.get(null));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                throw new DdlException("Failed to get config '" + confKey + "'. err: " + e.getMessage());
            }
            
            config.add(confKey);
            config.add(Strings.nullToEmpty(confVal));
            config.add(f.getType().getSimpleName());
            config.add(String.valueOf(anno.mutable()));
            config.add(String.valueOf(anno.masterOnly()));
            config.add(anno.comment());
            configs.add(config);
        }

        return configs;
    }

    public synchronized static boolean checkIsMasterOnly(String key) {
        Map<String, Field> mutableConfigs = getAllMutableConfigs();
        Field f = mutableConfigs.get(key);
        if (f == null) {
            return false;
        }

        ConfField anno = f.getAnnotation(ConfField.class);
        if (anno == null) {
            return false;
        }

        return anno.masterOnly();
    }
}
