/*
 * 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.skywalking.oap.server.core.hierarchy;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
import org.apache.skywalking.oap.server.core.analysis.Layer;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import org.apache.skywalking.oap.server.core.config.HierarchyDefinitionService;
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelation;
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelation;
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
import org.apache.skywalking.oap.server.core.query.type.Service;
import org.apache.skywalking.oap.server.core.source.SourceReceiver;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.util.RunnableWithExceptionProtection;

@Slf4j
public class HierarchyService implements org.apache.skywalking.oap.server.library.module.Service {
    private final ModuleManager moduleManager;
    private final boolean isEnableHierarchy;
    private SourceReceiver sourceReceiver;
    private MetadataQueryService metadataQueryService;
    private Map<String, Map<String, HierarchyDefinitionService.MatchingRule>> hierarchyDefinition;

    public HierarchyService(ModuleManager moduleManager, CoreModuleConfig moduleConfig) {
        this.moduleManager = moduleManager;
        this.isEnableHierarchy = moduleConfig.isEnableHierarchy();
    }

    private SourceReceiver getSourceReceiver() {
        if (sourceReceiver == null) {
            this.sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class);
        }
        return sourceReceiver;

    }

    private Map<String, Map<String, HierarchyDefinitionService.MatchingRule>> getHierarchyDefinition() {
        if (hierarchyDefinition == null) {
            hierarchyDefinition = moduleManager.find(CoreModule.NAME)
                                               .provider()
                                               .getService(HierarchyDefinitionService.class).getHierarchyDefinition();
        }
        return hierarchyDefinition;
    }

    private MetadataQueryService getMetadataQueryService() {
        if (metadataQueryService == null) {
            this.metadataQueryService = moduleManager.find(CoreModule.NAME)
                                                     .provider()
                                                     .getService(MetadataQueryService.class);
        }
        return metadataQueryService;
    }

    /**
     * Build the hierarchy relation between the 2 services. the `serviceLayer` and `relatedServiceLayer` hierarchy
     * relations should be defined in `config/hierarchy-definition.yml`.
     *
     * @param upperServiceName         the name of the service
     * @param upperServiceLayer        the layer of the service
     * @param lowerServiceName  the name of the lower service
     * @param lowerServiceLayer the layer of the lower service
     */
    public void toServiceHierarchyRelation(String upperServiceName,
                                           Layer upperServiceLayer,
                                           String lowerServiceName,
                                           Layer lowerServiceLayer) {
        if (!this.isEnableHierarchy) {
            return;
        }
        Map<String, HierarchyDefinitionService.MatchingRule> lowerLayers = getHierarchyDefinition().get(upperServiceLayer.name());
        if (lowerLayers == null || !lowerLayers.containsKey(lowerServiceLayer.name())) {
            log.error("upperServiceLayer " + upperServiceLayer.name() + " or lowerServiceLayer " + lowerServiceLayer.name()
                          + " is not defined in hierarchy-definition.yml.");
            return;
        }
        autoMatchingServiceRelation(upperServiceName, upperServiceLayer, lowerServiceName, lowerServiceLayer);
    }

    /**
     * Build the hierarchy relation between the 2 instances. the `serviceLayer` and `relatedServiceLayer` hierarchy
     * relations should be defined in `config/hierarchy-definition.yml`.
     *
     * @param upperInstanceName        the name of the upper instance
     * @param upperServiceName         the name of the upper service
     * @param upperServiceLayer        the layer of the upper service
     * @param lowerInstanceName the name of the lower related instance
     * @param lowerServiceName  the name of the lower related service
     * @param lowerServiceLayer the layer of the lower related service
     */
    public void toInstanceHierarchyRelation(String upperInstanceName,
                                            String upperServiceName,
                                            Layer upperServiceLayer,
                                            String lowerInstanceName,
                                            String lowerServiceName,
                                            Layer lowerServiceLayer) {
        if (!this.isEnableHierarchy) {
            return;
        }
        Map<String, HierarchyDefinitionService.MatchingRule> lowerLayers = getHierarchyDefinition().get(upperServiceLayer.name());
        if (lowerLayers == null || !lowerLayers.containsKey(lowerServiceLayer.name())) {
            log.error("upperServiceLayer " + upperServiceLayer.name() + " or lowerServiceLayer " + lowerServiceLayer.name()
                          + " is not defined in hierarchy-definition.yml.");
            return;
        }

        buildInstanceHierarchyRelation(upperInstanceName, upperServiceName, upperServiceLayer, lowerInstanceName,
                                           lowerServiceName, lowerServiceLayer);
    }

    public void startAutoMatchingServiceHierarchy() {
        if (!this.isEnableHierarchy) {
            return;
        }
        Executors.newSingleThreadScheduledExecutor()
                 .scheduleWithFixedDelay(
                     new RunnableWithExceptionProtection(this::autoMatchingServiceRelation, t -> log.error(
                         "Scheduled auto matching service hierarchy from service traffic failure.", t)), 30, 20, TimeUnit.SECONDS);
    }

    private void autoMatchingServiceRelation(String upperServiceName,
                                             Layer upperServiceLayer,
                                             String lowerServiceName,
                                             Layer lowerServiceLayer) {
        ServiceHierarchyRelation serviceHierarchy = new ServiceHierarchyRelation();
        serviceHierarchy.setServiceName(upperServiceName);
        serviceHierarchy.setServiceLayer(upperServiceLayer);
        serviceHierarchy.setRelatedServiceName(lowerServiceName);
        serviceHierarchy.setRelatedServiceLayer(lowerServiceLayer);
        serviceHierarchy.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
        this.getSourceReceiver().receive(serviceHierarchy);
    }

    private void buildInstanceHierarchyRelation(String upperInstanceName,
                                                String upperServiceName,
                                                Layer upperServiceLayer,
                                                String lowerInstanceName,
                                                String lowerServiceName,
                                                Layer lowerServiceLayer) {
        InstanceHierarchyRelation instanceHierarchy = new InstanceHierarchyRelation();
        instanceHierarchy.setInstanceName(upperInstanceName);
        instanceHierarchy.setServiceName(upperServiceName);
        instanceHierarchy.setServiceLayer(upperServiceLayer);
        instanceHierarchy.setRelatedInstanceName(lowerInstanceName);
        instanceHierarchy.setRelatedServiceName(lowerServiceName);
        instanceHierarchy.setRelatedServiceLayer(lowerServiceLayer);
        instanceHierarchy.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
        this.getSourceReceiver().receive(instanceHierarchy);
    }

    private void autoMatchingServiceRelation() {
        List<Service> allServices = getMetadataQueryService().listAllServices()
                                                             .values()
                                                             .stream()
                                                             .flatMap(List::stream)
                                                             .collect(Collectors.toList());
        if (allServices.size() > 1) {
            for (int i = 0; i < allServices.size(); i++) {
                for (int j = i + 1; j < allServices.size(); j++) {
                    Service service = allServices.get(i);
                    Service comparedService = allServices.get(j);
                    String serviceLayer = service.getLayers().iterator().next();
                    String comparedServiceLayer = comparedService.getLayers().iterator().next();
                    Map<String, HierarchyDefinitionService.MatchingRule> lowerLayers = getHierarchyDefinition().get(
                        serviceLayer);
                    Map<String, HierarchyDefinitionService.MatchingRule> comparedLowerLayers = getHierarchyDefinition().get(
                        comparedServiceLayer);
                    if (lowerLayers != null && lowerLayers.get(comparedServiceLayer) != null) {
                        try {
                            if (lowerLayers.get(comparedServiceLayer)
                                           .getClosure()
                                           .call(service, comparedService)) {
                                autoMatchingServiceRelation(service.getName(), Layer.nameOf(serviceLayer),
                                                            comparedService.getName(),
                                                            Layer.nameOf(comparedServiceLayer)
                                );
                            }
                        } catch (Throwable e) {
                            log.error(
                                "Auto matching service hierarchy from service traffic failure. Upper layer {}, lower layer {}, closure{}",
                                serviceLayer,
                                comparedServiceLayer,
                                lowerLayers.get(comparedServiceLayer).getExpression(), e
                            );
                        }

                    } else if (comparedLowerLayers != null && comparedLowerLayers.get(serviceLayer) != null) {
                        try {
                            if (comparedLowerLayers.get(serviceLayer)
                                                   .getClosure()
                                                   .call(comparedService, service)) {
                                autoMatchingServiceRelation(
                                    comparedService.getName(),
                                    Layer.nameOf(comparedServiceLayer),
                                    service.getName(),
                                    Layer.nameOf(serviceLayer)
                                );
                            }
                        } catch (Throwable e) {
                            log.error(
                                "Auto matching service hierarchy from service traffic failure. Upper layer {}, lower layer {}, closure{}",
                                comparedServiceLayer,
                                serviceLayer,
                                comparedLowerLayers.get(serviceLayer).getExpression(), e
                            );
                        }
                    }
                }
            }
        }
    }
}
