/*
 * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.microprofile.restclient;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.client.WebTarget;

/**
 * Model of the rest client interface.
 *
 * @author David Kral
 * @author Patrik Dudits
 */
class RestClientModel {

    private final InterfaceModel interfaceModel;
    private final Map<Method, MethodModel> methodModels;

    /**
     * Creates new instance of the {@link RestClientModel} base on interface class.
     *
     * @param context RestClient data context
     * @return new instance
     */
    static RestClientModel from(RestClientContext context) {
        InterfaceModel interfaceModel = InterfaceModel.from(context);
        return new Builder()
                .interfaceModel(interfaceModel)
                .methodModels(parseMethodModels(interfaceModel))
                .build();
    }

    private RestClientModel(Builder builder) {
        this.interfaceModel = builder.classModel;
        this.methodModels = builder.methodModels;
    }

    /**
     * Invokes desired rest client method.
     *
     * @param baseWebTarget path to endpoint
     * @param method        desired method
     * @param args          actual method parameters
     * @return method return value
     */
    <T> Object invokeMethod(WebTarget baseWebTarget, Method method, Object[] args) {
        WebTarget classLevelTarget = baseWebTarget.path(interfaceModel.getPath());
        MethodModel methodModel = methodModels.get(method);
        if (methodModel != null) {
            return new InterceptorInvocationContext(classLevelTarget, methodModel, method, args).proceed();
        }
        try {
            if (method.isDefault()) {
                T instance = (T) ReflectionUtil.createProxyInstance(interfaceModel.getRestClientClass());
                return method.invoke(instance, args);
            } else {
                throw new UnsupportedOperationException("This method is not supported!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Map<Method, MethodModel> parseMethodModels(InterfaceModel classModel) {
        Map<Method, MethodModel> methodMap = new HashMap<>();
        for (Method method : classModel.getRestClientClass().getMethods()) {
            if (method.isDefault() || Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            //Skip method processing if method does not have HTTP annotation
            //and is not sub resource (does not have Path annotation)
            methodMap.put(method, MethodModel.from(classModel, method));
        }
        return methodMap;
    }

    private static class Builder {

        private InterfaceModel classModel;
        private Map<Method, MethodModel> methodModels;

        private Builder() {
        }

        /**
         * Rest client class converted to {@link InterfaceModel}
         *
         * @param classModel {@link InterfaceModel} instance
         * @return Updated Builder instance
         */
        Builder interfaceModel(InterfaceModel classModel) {
            this.classModel = classModel;
            return this;
        }

        /**
         * Rest client class methods converted to {@link Map} of {@link MethodModel}
         *
         * @param methodModels Method models
         * @return Updated Builder instance
         */
        Builder methodModels(Map<Method, MethodModel> methodModels) {
            this.methodModels = methodModels;
            return this;
        }

        /**
         * Creates new RestClientModel instance.
         *
         * @return new instance
         */
        public RestClientModel build() {
            return new RestClientModel(this);
        }
    }

    @Override
    public String toString() {
        return interfaceModel.getRestClientClass().getName();
    }
}
