/*
 * 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.meecrowave.cxf;

import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonBuilderFactory;
import javax.json.JsonMergePatch;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonPatch;
import javax.json.JsonPatchBuilder;
import javax.json.JsonPointer;
import javax.json.JsonReader;
import javax.json.JsonReaderFactory;
import javax.json.JsonString;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import javax.json.JsonWriter;
import javax.json.JsonWriterFactory;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.spi.JsonProvider;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParserFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

import org.apache.cxf.bus.extension.ExtensionManagerBus;
import org.apache.cxf.bus.managers.ClientLifeCycleManagerImpl;
import org.apache.cxf.endpoint.ClientLifeCycleManager;
import org.apache.johnzon.core.AbstractJsonFactory;
import org.apache.johnzon.core.JsonGeneratorFactoryImpl;
import org.apache.johnzon.core.JsonParserFactoryImpl;
import org.apache.johnzon.jaxrs.DelegateProvider;
import org.apache.johnzon.jaxrs.JsrMessageBodyReader;
import org.apache.johnzon.jaxrs.JsrMessageBodyWriter;
import org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider;
import org.apache.meecrowave.Meecrowave;

public class ConfigurableBus extends ExtensionManagerBus {
    public void initProviders(final Meecrowave.Builder builder,
                              final ClassLoader loader) {
        final List<Object> providers =
                ofNullable(builder.getJaxrsDefaultProviders())
                        .map(s -> Stream.of(s.split(" *, *"))
                                .map(String::trim)
                                .filter(p -> !p.isEmpty())
                                .map(name -> {
                                    try {
                                        return Thread.currentThread().getContextClassLoader().loadClass(name).newInstance();
                                    } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                                        throw new IllegalArgumentException(name + " can't be created");
                                    }
                                })
                                .collect(Collectors.<Object>toList()))
                        .orElseGet(() -> {
                            // ensure both providers share the same memory reuse logic
                            final JsonProvider provider = JsonProvider.provider();
                            final JsonReaderFactory readerFactory = provider.createReaderFactory(
                                    new HashMap<String, Object>() {{
                                        put(JsonParserFactoryImpl.SUPPORTS_COMMENTS, builder.isJsonpSupportsComment());
                                        Optional.of(builder.getJsonpMaxStringLen()).filter(v -> v > 0)
                                                .ifPresent(s -> put(JsonParserFactoryImpl.MAX_STRING_LENGTH,
                                                        s));
                                        Optional.of(builder.getJsonpMaxReadBufferLen()).filter(v -> v > 0)
                                                .ifPresent(s -> put(JsonParserFactoryImpl.BUFFER_LENGTH,
                                                        s));
                                        ofNullable(builder.getJsonpBufferStrategy()).ifPresent(
                                                s -> put(AbstractJsonFactory.BUFFER_STRATEGY, s));
                                    }});
                            final JsonWriterFactory writerFactory = provider.createWriterFactory(
                                    new HashMap<String, Object>() {{
                                        put(JsonGenerator.PRETTY_PRINTING, builder.isJsonpPrettify());
                                        Optional.of(builder.getJsonpMaxWriteBufferLen()).filter(v -> v > 0)
                                                .ifPresent(v -> put(
                                                        JsonGeneratorFactoryImpl
                                                                .GENERATOR_BUFFER_LENGTH,
                                                        v));
                                        ofNullable(builder.getJsonpBufferStrategy()).ifPresent(
                                                s -> put(AbstractJsonFactory.BUFFER_STRATEGY, s));
                                    }});
                            return Stream.<Object>of(
                                    new ConfiguredJsonbJaxrsProvider(
                                            builder.getJsonbEncoding(), builder.isJsonbNulls(),
                                            builder.isJsonbIJson(), builder.isJsonbPrettify(),
                                            builder.getJsonbBinaryStrategy(), builder.getJsonbNamingStrategy(),
                                            builder.getJsonbOrderStrategy(),
                                            new DelegateJsonProvider(provider, readerFactory, writerFactory)),
                                    new ConfiguredJsrProvider(readerFactory, writerFactory))
                                    .collect(toList());
                        });

        if (builder.isJaxrsAutoActivateBeanValidation()) {
            try { // we don't need the jaxrsbeanvalidationfeature since bean validation cdi extension handles it normally
                loader.loadClass("javax.validation.Validation");
                final Object instance = loader.loadClass("org.apache.cxf.jaxrs.validation.ValidationExceptionMapper")
                        .getConstructor().newInstance();
                instance.getClass().getGenericInterfaces(); // validate bval can be used, check NoClassDefFoundError javax.validation.ValidationException
                providers.add(instance);
            } catch (final Exception | NoClassDefFoundError e) {
                // no-op
            }
        }

        // client
        if (getProperty("org.apache.cxf.jaxrs.bus.providers") == null) {
            setProperty("skip.default.json.provider.registration", "true");
            setProperty("org.apache.cxf.jaxrs.bus.providers", providers);
        }
    }

    public void addClientLifecycleListener() {
        ClientLifeCycleManager manager = getExtension(ClientLifeCycleManager.class);
        if (manager == null) {
            manager = new ClientLifeCycleManagerImpl();
            setExtension(manager, ClientLifeCycleManager.class);
        }
        manager.registerListener(new MeecrowaveClientLifecycleListener());
    }

    @Provider
    @Produces({MediaType.APPLICATION_JSON, "*/*+json"})
    @Consumes({MediaType.APPLICATION_JSON, "*/*+json"})
    public static class ConfiguredJsonbJaxrsProvider<T> extends JsonbJaxrsProvider<T> {
        private final Jsonb jsonb;

        private ConfiguredJsonbJaxrsProvider(final String encoding,
                                             final boolean nulls,
                                             final boolean iJson,
                                             final boolean pretty,
                                             final String binaryStrategy,
                                             final String namingStrategy,
                                             final String orderStrategy,
                                             final JsonProvider provider) {
            // ATTENTION this is only a workaround for MEECROWAVE-49 and shall get removed after Johnzon has a fix for it!
            // We add byte[] to the ignored types.
            super(singletonList("[B"));
            ofNullable(encoding).ifPresent(this::setEncoding);
            ofNullable(namingStrategy).ifPresent(this::setPropertyNamingStrategy);
            ofNullable(orderStrategy).ifPresent(this::setPropertyOrderStrategy);
            ofNullable(binaryStrategy).ifPresent(this::setBinaryDataStrategy);
            setNullValues(nulls);
            setIJson(iJson);
            setPretty(pretty);
            this.jsonb = JsonbBuilder.newBuilder()
                    .withProvider(provider)
                    .withConfig(config)
                    .build();
        }

        @Override
        protected Jsonb createJsonb() {
            return jsonb;
        }
    }

    @Provider
    @Produces({MediaType.APPLICATION_JSON, "application/*+json"})
    @Consumes({MediaType.APPLICATION_JSON, "application/*+json"})
    public static class ConfiguredJsrProvider extends DelegateProvider<JsonStructure> { // TODO: probably wire the encoding in johnzon
        private ConfiguredJsrProvider(final JsonReaderFactory readerFactory,
                                      final JsonWriterFactory writerFactory) {
            super(new JsrMessageBodyReader(readerFactory, false), new JsrMessageBodyWriter(writerFactory, false));
        }
    }

    private static class DelegateJsonProvider extends JsonProvider {
        private final JsonReaderFactory readerFactory;
        private final JsonWriterFactory writerFactory;
        private final JsonProvider provider;

        private DelegateJsonProvider(final JsonProvider provider, final JsonReaderFactory readerFactory, final JsonWriterFactory writerFactory) {
            this.provider = provider;
            this.readerFactory = readerFactory;
            this.writerFactory = writerFactory;
        }

        @Override
        public JsonWriterFactory createWriterFactory(final Map<String, ?> config) {
            return writerFactory;
        }

        @Override
        public JsonReaderFactory createReaderFactory(final Map<String, ?> config) {
            return readerFactory;
        }

        @Override
        public JsonParser createParser(final Reader reader) {
            return provider.createParser(reader);
        }

        @Override
        public JsonParser createParser(final InputStream in) {
            return provider.createParser(in);
        }

        @Override
        public JsonParserFactory createParserFactory(final Map<String, ?> config) {
            return provider.createParserFactory(config);
        }

        @Override
        public JsonGenerator createGenerator(final Writer writer) {
            return provider.createGenerator(writer);
        }

        @Override
        public JsonGenerator createGenerator(final OutputStream out) {
            return provider.createGenerator(out);
        }

        @Override
        public JsonGeneratorFactory createGeneratorFactory(final Map<String, ?> config) {
            return provider.createGeneratorFactory(config);
        }

        @Override
        public JsonReader createReader(final Reader reader) {
            return provider.createReader(reader);
        }

        @Override
        public JsonReader createReader(final InputStream in) {
            return provider.createReader(in);
        }

        @Override
        public JsonWriter createWriter(final Writer writer) {
            return provider.createWriter(writer);
        }

        @Override
        public JsonWriter createWriter(final OutputStream out) {
            return provider.createWriter(out);
        }

        @Override
        public JsonObjectBuilder createObjectBuilder() {
            return provider.createObjectBuilder();
        }

        @Override
        public JsonObjectBuilder createObjectBuilder(final JsonObject jsonObject) {
            return provider.createObjectBuilder(jsonObject);
        }

        @Override
        public JsonObjectBuilder createObjectBuilder(final Map<String, Object> map) {
            return provider.createObjectBuilder(map);
        }

        @Override
        public JsonArrayBuilder createArrayBuilder() {
            return provider.createArrayBuilder();
        }

        @Override
        public JsonArrayBuilder createArrayBuilder(final JsonArray initialData) {
            return provider.createArrayBuilder(initialData);
        }

        @Override
        public JsonArrayBuilder createArrayBuilder(final Collection<?> initialData) {
            return provider.createArrayBuilder(initialData);
        }

        @Override
        public JsonPointer createPointer(final String path) {
            return provider.createPointer(path);
        }

        @Override
        public JsonBuilderFactory createBuilderFactory(final Map<String, ?> config) {
            return provider.createBuilderFactory(config);
        }

        @Override
        public JsonString createValue(final String value) {
            return provider.createValue(value);
        }

        @Override
        public JsonNumber createValue(final int value) {
            return provider.createValue(value);
        }

        @Override
        public JsonNumber createValue(final long value) {
            return provider.createValue(value);
        }

        @Override
        public JsonNumber createValue(final double value) {
            return provider.createValue(value);
        }

        @Override
        public JsonNumber createValue(final BigDecimal value) {
            return provider.createValue(value);
        }

        @Override
        public JsonNumber createValue(final BigInteger value) {
            return provider.createValue(value);
        }

        @Override
        public JsonPatch createPatch(final JsonArray array) {
            return provider.createPatch(array);
        }

        @Override
        public JsonPatch createDiff(final JsonStructure source, final JsonStructure target) {
            return provider.createDiff(source, target);
        }

        @Override
        public JsonPatchBuilder createPatchBuilder() {
            return provider.createPatchBuilder();
        }

        @Override
        public JsonPatchBuilder createPatchBuilder(final JsonArray initialData) {
            return provider.createPatchBuilder(initialData);
        }

        @Override
        public JsonMergePatch createMergePatch(final JsonValue patch) {
            return provider.createMergePatch(patch);
        }

        @Override
        public JsonMergePatch createMergeDiff(final JsonValue source, final JsonValue target) {
            return provider.createMergeDiff(source, target);
        }
    }
}
