/*
 * 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.dubbo.common.utils;

import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST;
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST;
import static org.apache.dubbo.common.constants.CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL;
import static org.apache.dubbo.common.constants.CommonConstants.SERIALIZE_BLOCKED_LIST_FILE_PATH;

public class SerializeClassChecker {
    private static final Logger logger = LoggerFactory.getLogger(SerializeClassChecker.class);

    private static volatile SerializeClassChecker INSTANCE = null;

    private final boolean OPEN_CHECK_CLASS;
    private final boolean BLOCK_ALL_CLASS_EXCEPT_ALLOW;
    private final Set<String> CLASS_DESERIALIZE_ALLOWED_SET = new ConcurrentHashSet<>();
    private final Set<String> CLASS_DESERIALIZE_BLOCKED_SET = new ConcurrentHashSet<>();

    private final Object CACHE = new Object();
    private final LFUCache<String, Object> CLASS_ALLOW_LFU_CACHE = new LFUCache<>();
    private final LFUCache<String, Object> CLASS_BLOCK_LFU_CACHE = new LFUCache<>();

    private final AtomicLong counter = new AtomicLong(0);

    private SerializeClassChecker() {
        String openCheckClass = ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
        OPEN_CHECK_CLASS = Boolean.parseBoolean(openCheckClass);

        String blockAllClassExceptAllow = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
        
        BLOCK_ALL_CLASS_EXCEPT_ALLOW = Boolean.parseBoolean(blockAllClassExceptAllow);

        String[] lines;
        try {
            ClassLoader classLoader = ClassUtils.getClassLoader(JavaBeanSerializeUtil.class);
            if (classLoader != null) {
                lines = IOUtils.readLines(classLoader.getResourceAsStream(SERIALIZE_BLOCKED_LIST_FILE_PATH));
            } else {
                lines = IOUtils.readLines(ClassLoader.getSystemResourceAsStream(SERIALIZE_BLOCKED_LIST_FILE_PATH));
            }
            for (String line : lines) {
                line = line.trim();
                if (StringUtils.isEmpty(line) || line.startsWith("#")) {
                    continue;
                }
                CLASS_DESERIALIZE_BLOCKED_SET.add(line);
            }

        } catch (IOException e) {
            logger.error("Failed to load blocked class list! Will ignore default blocked list.", e);
        }

        String allowedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
        String blockedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);

        if (StringUtils.isNotEmpty(allowedClassList)) {
            String[] classStrings = allowedClassList.trim().split(",");
            CLASS_DESERIALIZE_ALLOWED_SET.addAll(Arrays.asList(classStrings));
        }

        if (StringUtils.isNotEmpty(blockedClassList)) {
            String[] classStrings = blockedClassList.trim().split(",");
            CLASS_DESERIALIZE_BLOCKED_SET.addAll(Arrays.asList(classStrings));
        }

    }

    public static SerializeClassChecker getInstance() {
        if (INSTANCE == null) {
            synchronized (SerializeClassChecker.class) {
                if (INSTANCE == null) {
                    INSTANCE = new SerializeClassChecker();
                }
            }
        }
        return INSTANCE;
    }

    /**
     * For ut only
     */
    @Deprecated
    protected static void clearInstance() {
        INSTANCE = null;
    }

    /**
     * Check if a class is in block list, using prefix match
     *
     * @throws IllegalArgumentException if class is blocked
     * @param name class name ( all are convert to lower case )
     */
    public void validateClass(String name) {
        if(!OPEN_CHECK_CLASS){
            return;
        }

        name = name.toLowerCase(Locale.ROOT);
        if (CACHE == CLASS_ALLOW_LFU_CACHE.get(name)) {
            return;
        }

        if (CACHE == CLASS_BLOCK_LFU_CACHE.get(name)) {
            error(name);
        }

        for (String allowedPrefix : CLASS_DESERIALIZE_ALLOWED_SET) {
            if (name.startsWith(allowedPrefix)) {
                CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
                return;
            }
        }

        for (String blockedPrefix : CLASS_DESERIALIZE_BLOCKED_SET) {
            if (BLOCK_ALL_CLASS_EXCEPT_ALLOW || name.startsWith(blockedPrefix)) {
                CLASS_BLOCK_LFU_CACHE.put(name, CACHE);
                error(name);
            }
        }

        CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
    }

    private void error(String name) {
        String notice = "Trigger the safety barrier! " +
                "Catch not allowed serialize class. " +
                "Class name: " + name + " . " +
                "This means currently maybe being attacking by others." +
                "If you are sure this is a mistake, " +
                "please add this class name to `" + CLASS_DESERIALIZE_ALLOWED_LIST +
                "` as a system environment property.";
        if (counter.incrementAndGet() % 1000 == 0 || counter.get() < 100) {
            logger.error(notice);
        }
        throw new IllegalArgumentException(notice);
    }

}
