/*-
 * ~~~~~~licensing~~~~~~
 * service-runtime
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.services.runtime.interceptor;

import java.net.URL;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.transport.http.Headers;
import org.apache.karaf.jaas.boot.principal.UserPrincipal;

@Deprecated(since = "1.10", forRemoval = true)
public class IsSchemaDisplayInterceptor extends AbstractPhaseInterceptor<Message> {

    private static final Log LOG = LogFactory.getLog(IsSchemaDisplayInterceptor.class);

    public static final List<String> SERVICE_SCHEMA_QUERY = new ArrayList<>();
    public static final List<String> SERVICE_SCHEMA_FILE = new ArrayList<>();

    static {
        SERVICE_SCHEMA_QUERY.add("wsdl");
        SERVICE_SCHEMA_QUERY.add("wadl");
        SERVICE_SCHEMA_QUERY.add("swagger.json");
        SERVICE_SCHEMA_QUERY.add("open-api.json");
        SERVICE_SCHEMA_QUERY.add("open-api.yaml");

        SERVICE_SCHEMA_FILE.add(".*\\/openapi\\.json");
        SERVICE_SCHEMA_FILE.add(".*\\/openapi\\.yaml");
        SERVICE_SCHEMA_FILE.add(".*api-docs");
        SERVICE_SCHEMA_FILE.add(".*\\/swagger-ui[^.]*\\.\\w*");
    }

    public boolean isDisplayServiceSchema;

    public IsSchemaDisplayInterceptor() {
        super(Phase.RECEIVE);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        Map<String, List<String>> headers = Headers.getSetProtocolHeaders(message);

        boolean isAllowedSchemaRequest = checkOnSchema(message);

        if (isAllowedSchemaRequest) {
            // we create simple SecurityContext with anonymous user
            message.put(SecurityContext.class, new AnonymousSecurityContext());
        }

        headers.put(SystemHeadersConstants.HEADER_IS_DISPLAY_SERVICE_SERVICE,
                Collections.singletonList(String.valueOf(isAllowedSchemaRequest)));
    }

    private boolean checkOnSchema(Message message) {

        if (!isDisplayServiceSchema)
            return false;

        Object params = message.get(Message.QUERY_STRING);

        for (String schema : SERVICE_SCHEMA_QUERY) {
            if (params != null && Pattern.matches(schema, params.toString()))
                return true;
        }

        params = message.get(Message.REQUEST_URL);
        try {
            URL requestUrl = new URL(params.toString());
            for (String schema : SERVICE_SCHEMA_FILE) {
                if (Pattern.matches(schema, requestUrl.getFile()))
                    return true;
            }
        } catch (Exception e) {

        }

        return false;
    }

    public boolean isDisplayServiceSchema() {
        return isDisplayServiceSchema;
    }

    public void setIsDisplayServiceSchema(boolean displayServiceSchema) {
        this.isDisplayServiceSchema = displayServiceSchema;
    }

    protected static class AnonymousSecurityContext implements SecurityContext {

        public static final String ANONYMOUS_USER_NAME = "anonymous";

        protected static Principal ANONYMOUS_USER = new UserPrincipal(ANONYMOUS_USER_NAME);

        @Override
        public Principal getUserPrincipal() {
            return ANONYMOUS_USER;
        }

        @Override
        public boolean isUserInRole(String role) {
            return false;
        }

    }
}
