/*
 * 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.rpc.protocol.rest;

import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.metadata.extension.rest.api.PathMatcher;
import org.apache.dubbo.metadata.extension.rest.api.RestMethodMetadata;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.protocol.rest.exception.DoublePathCheckException;
import org.apache.dubbo.rpc.protocol.rest.pair.InvokerAndRestMethodMetadataPair;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * save the path & metadata info mapping
 */
public class PathAndInvokerMapper {
    private static final ErrorTypeAwareLogger logger =
            LoggerFactory.getErrorTypeAwareLogger(PathAndInvokerMapper.class);

    private final Map<PathMatcher, InvokerAndRestMethodMetadataPair> pathToServiceMapContainPathVariable =
            new ConcurrentHashMap<>();
    private final Map<PathMatcher, InvokerAndRestMethodMetadataPair> pathToServiceMapNoPathVariable =
            new ConcurrentHashMap<>();

    // for http method compare 405
    private final Map<PathMatcher, Set<String>> pathMatcherToHttpMethodMap = new HashMap<>();

    /**
     * deploy path metadata
     *
     * @param metadataMap
     * @param invoker
     */
    public void addPathAndInvoker(Map<PathMatcher, RestMethodMetadata> metadataMap, Invoker invoker) {

        metadataMap.entrySet().stream().forEach(entry -> {
            PathMatcher pathMatcher = entry.getKey();
            if (pathMatcher.hasPathVariable()) {
                addPathMatcherToPathMap(
                        pathMatcher,
                        pathToServiceMapContainPathVariable,
                        InvokerAndRestMethodMetadataPair.pair(invoker, entry.getValue()));
            } else {
                addPathMatcherToPathMap(
                        pathMatcher,
                        pathToServiceMapNoPathVariable,
                        InvokerAndRestMethodMetadataPair.pair(invoker, entry.getValue()));
            }
        });
    }

    /**
     * get rest method metadata by path matcher
     *
     * @param pathMatcher
     * @return
     */
    public InvokerAndRestMethodMetadataPair getRestMethodMetadata(PathMatcher pathMatcher) {

        // first search from pathToServiceMapNoPathVariable
        if (pathToServiceMapNoPathVariable.containsKey(pathMatcher)) {
            return pathToServiceMapNoPathVariable.get(pathMatcher);
        }

        // second search from pathToServiceMapContainPathVariable
        if (pathToServiceMapContainPathVariable.containsKey(pathMatcher)) {
            return pathToServiceMapContainPathVariable.get(pathMatcher);
        }

        return null;
    }

    /**
     * undeploy path metadata
     *
     * @param pathMatcher
     */
    public void removePath(PathMatcher pathMatcher) {

        InvokerAndRestMethodMetadataPair containPathVariablePair =
                pathToServiceMapContainPathVariable.remove(pathMatcher);

        InvokerAndRestMethodMetadataPair unContainPathVariablePair = pathToServiceMapNoPathVariable.remove(pathMatcher);
        logger.info("dubbo rest undeploy pathMatcher:" + pathMatcher
                + ", and path variable method is :"
                + (containPathVariablePair == null
                        ? null
                        : containPathVariablePair.getRestMethodMetadata().getReflectMethod())
                + ", and no path variable  method is :"
                + (unContainPathVariablePair == null
                        ? null
                        : unContainPathVariablePair.getRestMethodMetadata().getReflectMethod()));
    }

    public void addPathMatcherToPathMap(
            PathMatcher pathMatcher,
            Map<PathMatcher, InvokerAndRestMethodMetadataPair> pathMatcherPairMap,
            InvokerAndRestMethodMetadataPair invokerRestMethodMetadataPair) {

        if (pathMatcherPairMap.containsKey(pathMatcher)) {

            // cover the old service metadata when  current interface is old interface & current method desc equals
            // old`s method desc,else ,throw double check exception

            InvokerAndRestMethodMetadataPair beforeMetadata = pathMatcherPairMap.get(pathMatcher);
            // true when reExport
            if (!invokerRestMethodMetadataPair.compareServiceMethod(beforeMetadata)) {
                throw new DoublePathCheckException("dubbo rest double path check error, current path is: " + pathMatcher
                        + " ,and service method is: "
                        + invokerRestMethodMetadataPair.getRestMethodMetadata().getReflectMethod()
                        + "before service  method is: "
                        + beforeMetadata.getRestMethodMetadata().getReflectMethod());
            }
        }

        pathMatcherPairMap.put(pathMatcher, invokerRestMethodMetadataPair);

        addPathMatcherToHttpMethodsMap(pathMatcher);

        logger.info("dubbo rest deploy pathMatcher:" + pathMatcher + ", and service method is :"
                + invokerRestMethodMetadataPair.getRestMethodMetadata().getReflectMethod());
    }

    private void addPathMatcherToHttpMethodsMap(PathMatcher pathMatcher) {

        PathMatcher newPathMatcher = PathMatcher.convertPathMatcher(pathMatcher);

        if (!pathMatcherToHttpMethodMap.containsKey(newPathMatcher)) {
            HashSet<String> httpMethods = new HashSet<>();

            httpMethods.add(pathMatcher.getHttpMethod());

            pathMatcherToHttpMethodMap.put(newPathMatcher, httpMethods);
        }

        Set<String> httpMethods = pathMatcherToHttpMethodMap.get(newPathMatcher);

        httpMethods.add(newPathMatcher.getHttpMethod());
    }

    public boolean isHttpMethodAllowed(PathMatcher pathMatcher) {

        PathMatcher newPathMatcher = PathMatcher.convertPathMatcher(pathMatcher);
        if (!pathMatcherToHttpMethodMap.containsKey(newPathMatcher)) {
            return false;
        }

        Set<String> httpMethods = pathMatcherToHttpMethodMap.get(newPathMatcher);

        return httpMethods.contains(newPathMatcher.getHttpMethod());
    }

    public String pathHttpMethods(PathMatcher pathMatcher) {

        PathMatcher newPathMatcher = PathMatcher.convertPathMatcher(pathMatcher);
        if (!pathMatcherToHttpMethodMap.containsKey(newPathMatcher)) {
            return null;
        }

        Set<String> httpMethods = pathMatcherToHttpMethodMap.get(newPathMatcher);

        return httpMethods.toString();
    }
}
