/*
 * 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.spring.boot.actuate.health;

import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;

/**
 * Dubbo {@link HealthIndicator}
 *
 * @see HealthIndicator
 * @since 2.7.0
 */
public class DubboHealthIndicator extends AbstractHealthIndicator {

    @Autowired
    private DubboHealthIndicatorProperties dubboHealthIndicatorProperties;

    @Autowired(required = false)
    private Map<String, ProtocolConfig> protocolConfigs = Collections.emptyMap();

    @Autowired(required = false)
    private Map<String, ProviderConfig> providerConfigs = Collections.emptyMap();

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {

        ExtensionLoader<StatusChecker> extensionLoader = getExtensionLoader(StatusChecker.class);

        Map<String, String> statusCheckerNamesMap = resolveStatusCheckerNamesMap();

        boolean hasError = false;

        boolean hasUnknown = false;

        // Up first
        builder.up();

        for (Map.Entry<String, String> entry : statusCheckerNamesMap.entrySet()) {

            String statusCheckerName = entry.getKey();

            String source = entry.getValue();

            StatusChecker checker = extensionLoader.getExtension(statusCheckerName);

            org.apache.dubbo.common.status.Status status = checker.check();

            org.apache.dubbo.common.status.Status.Level level = status.getLevel();

            if (!hasError && level.equals(org.apache.dubbo.common.status.Status.Level.ERROR)) {
                hasError = true;
                builder.down();
            }

            if (!hasError && !hasUnknown && level.equals(org.apache.dubbo.common.status.Status.Level.UNKNOWN)) {
                hasUnknown = true;
                builder.unknown();
            }

            Map<String, Object> detail = new LinkedHashMap<>();

            detail.put("source", source);
            detail.put("status", status);

            builder.withDetail(statusCheckerName, detail);

        }


    }

    /**
     * Resolves the map of {@link StatusChecker}'s name and its' source.
     *
     * @return non-null {@link Map}
     */
    protected Map<String, String> resolveStatusCheckerNamesMap() {

        Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>();

        statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties());

        statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromProtocolConfigs());

        statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromProviderConfig());

        return statusCheckerNamesMap;

    }

    private Map<String, String> resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties() {

        DubboHealthIndicatorProperties.Status status =
                dubboHealthIndicatorProperties.getStatus();

        Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>();

        for (String statusName : status.getDefaults()) {

            statusCheckerNamesMap.put(statusName, DubboHealthIndicatorProperties.PREFIX + ".status.defaults");

        }

        for (String statusName : status.getExtras()) {

            statusCheckerNamesMap.put(statusName, DubboHealthIndicatorProperties.PREFIX + ".status.extras");

        }

        return statusCheckerNamesMap;

    }


    private Map<String, String> resolveStatusCheckerNamesMapFromProtocolConfigs() {

        Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>();

        for (Map.Entry<String, ProtocolConfig> entry : protocolConfigs.entrySet()) {

            String beanName = entry.getKey();

            ProtocolConfig protocolConfig = entry.getValue();

            Set<String> statusCheckerNames = getStatusCheckerNames(protocolConfig);

            for (String statusCheckerName : statusCheckerNames) {

                String source = buildSource(beanName, protocolConfig);

                statusCheckerNamesMap.put(statusCheckerName, source);

            }

        }

        return statusCheckerNamesMap;

    }

    private Map<String, String> resolveStatusCheckerNamesMapFromProviderConfig() {

        Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>();

        for (Map.Entry<String, ProviderConfig> entry : providerConfigs.entrySet()) {

            String beanName = entry.getKey();

            ProviderConfig providerConfig = entry.getValue();

            Set<String> statusCheckerNames = getStatusCheckerNames(providerConfig);

            for (String statusCheckerName : statusCheckerNames) {

                String source = buildSource(beanName, providerConfig);

                statusCheckerNamesMap.put(statusCheckerName, source);

            }

        }

        return statusCheckerNamesMap;

    }

    private Set<String> getStatusCheckerNames(ProtocolConfig protocolConfig) {
        String status = protocolConfig.getStatus();
        return StringUtils.commaDelimitedListToSet(status);
    }

    private Set<String> getStatusCheckerNames(ProviderConfig providerConfig) {
        String status = providerConfig.getStatus();
        return StringUtils.commaDelimitedListToSet(status);
    }

    private String buildSource(String beanName, Object bean) {
        return beanName + "@" + bean.getClass().getSimpleName() + ".getStatus()";
    }

}
