/*
 * 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.camel.springboot.openapi;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import io.apicurio.datamodels.openapi.models.OasDocument;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.apache.camel.CamelContext;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.openapi.BeanConfig;
import org.apache.camel.openapi.DefaultRestDefinitionsResolver;
import org.apache.camel.openapi.RestDefinitionsResolver;
import org.apache.camel.openapi.RestOpenApiReader;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.spring.boot.CamelContextConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;

import java.util.List;
import java.util.Map;

import static org.apache.camel.openapi.OpenApiHelper.clearVendorExtensions;

/**
 * Open API auto-configuration.
 */
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({OpenApiConfiguration.class})
@ConditionalOnBean(type = "org.apache.camel.spring.boot.CamelAutoConfiguration")
@ConditionalOnProperty(name = "camel.openapi.enabled", matchIfMissing = true)
@AutoConfigureAfter(name = "org.apache.camel.spring.boot.CamelAutoConfiguration")
@AutoConfigureBefore(name = "org.springdoc.core.SpringDocConfiguration")
public class OpenApiAutoConfiguration {

    private static final Logger LOG = LoggerFactory.getLogger(OpenApiAutoConfiguration.class);

    private final RestOpenApiReader reader = new RestOpenApiReader();
    private final RestDefinitionsResolver resolver = new DefaultRestDefinitionsResolver();
    private final OpenAPI openAPI = new OpenAPI();

    @Bean
    CamelContextConfiguration onBeforeStart(GenericApplicationContext ac, CamelContext camelContext, OpenApiConfiguration config) {
        return new CamelContextConfiguration() {
            @Override
            public void beforeApplicationStart(CamelContext camelContext) {
                // routes have now been loaded, so we need to detect rest-dsl APIs in Camel
                // this will trigger spring boot to create the bean which springdoc can detect
                try {
                    OpenAPI created = createOpenAPI(camelContext);
                    if (created != null) {
                        LOG.info("OpenAPI ({}) created from Camel Rest-DSL v{} - {}", created.getOpenapi(), created.getInfo().getVersion(), created.getInfo().getTitle());
                        // transfer data to the existing
                        openAPI.setInfo(created.getInfo());
                        openAPI.setOpenapi(created.getOpenapi());
                        if (created.getComponents() != null) {
                            openAPI.setComponents(created.getComponents());
                        }
                        if (created.getExtensions() != null) {
                            openAPI.setExtensions(created.getExtensions());
                        }
                        if (created.getSecurity() != null) {
                            openAPI.setSecurity(created.getSecurity());
                        }
                        if (created.getExternalDocs() != null) {
                            openAPI.setExternalDocs(created.getExternalDocs());
                        }
                        if (created.getPaths() != null) {
                            openAPI.setPaths(created.getPaths());
                        }
                        if (created.getTags() != null) {
                            openAPI.setTags(created.getTags());
                        }
                        // do not copy servers as we use the spring-boot configured setting
                    }
                } catch (Exception e) {
                    LOG.warn("Error generating OpenAPI from Camel Rest DSL due to: " + e.getMessage() + ". This exception is ignored.", e);
                }
            }

            @Override
            public void afterApplicationStart(CamelContext camelContext) {
                // noop
            }
        };
    }

    @Bean
    OpenAPI camelRestDSLOpenApi() {
        // due to ordering how beans are resolved and setup in spring boot, then we need to create
        // this provisional bean which is later updated with the actual Rest DSL APIs after the routes has been loaded
        // into Camel
        return openAPI;
    }

    private OpenAPI createOpenAPI(CamelContext camelContext) throws Exception {
        List<RestDefinition> rests = resolver.getRestDefinitions(camelContext, null);
        if (rests == null || rests.isEmpty()) {
            return null;
        }

        BeanConfig bc = new BeanConfig();
        Info info = new Info();

        RestConfiguration rc = camelContext.getRestConfiguration();
        initOpenApi(bc, info, rc.getApiProperties());

        OasDocument openApi = reader.read(camelContext, rests, "", bc, null, camelContext.getClassResolver());
        if (!rc.isApiVendorExtension()) {
            clearVendorExtensions(openApi);
        }

        // dump to json
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        Object dump = io.apicurio.datamodels.Library.writeNode(openApi);
        byte[] jsonData = mapper.writeValueAsBytes(dump);
        // json to yaml
        JsonNode node = mapper.readTree(jsonData);
        String yaml = new YAMLMapper().writeValueAsString(node);

        // parse bytes into swagger
        OpenAPIV3Parser parser = new OpenAPIV3Parser();
        SwaggerParseResult spr = parser.readContents(yaml);
        OpenAPI answer = spr.getOpenAPI();
        if (answer != null) {
            answer.setInfo(info);
        }
        return answer;
    }

    private static void initOpenApi(BeanConfig bc, Info info, Map<String, Object> config) {
        // configure openApi options
        String s = (String) config.get("openapi.version");
        if (s != null) {
            bc.setVersion(s);
        }
        s = (String) config.get("base.path");
        if (s != null) {
            bc.setBasePath(s);
        }
        s = (String) config.get("host");
        if (s != null) {
            bc.setHost(s);
        }
        s = (String) config.get("schemes");
        if (s == null) {
            // deprecated due typo
            s = (String) config.get("schemas");
        }
        if (s != null) {
            String[] schemes = s.split(",");
            bc.setSchemes(schemes);
        } else {
            // assume http by default
            bc.setSchemes(new String[] { "http" });
        }

        String version = (String) config.get("api.version");
        String title = (String) config.get("api.title");
        String description = (String) config.get("api.description");
        String termsOfService = (String) config.get("api.termsOfService");
        String licenseName = (String) config.get("api.license.name");
        String licenseUrl = (String) config.get("api.license.url");
        String contactName = (String) config.get("api.contact.name");
        String contactUrl = (String) config.get("api.contact.url");
        String contactEmail = (String) config.get("api.contact.email");

        bc.setTitle(title);
        bc.setLicense(licenseName);
        bc.setLicenseUrl(licenseUrl);

        info.setTitle(title);
        info.setVersion(version);
        info.setDescription(description);
        info.setTermsOfService(termsOfService);
        if (contactName != null) {
            Contact contact = new Contact();
            contact.setName(contactName);
            contact.setEmail(contactEmail);
            contact.setUrl(contactUrl);
            info.setContact(contact);
        }
    }

}
