/*
 * 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 javax.json.spi;

import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonBuilderFactory;
import javax.json.JsonException;
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.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParserFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * JsonProvider is the actual implementation of all the Json logic.
 * A JsonProvider instance can be used concurrently.
 *
 * It can be accessed via
 * <pre>
 *     <code>
 * JsonProvider provider = JsonProvider.provider();
 *     </code>
 * </pre>
 */
public abstract class JsonProvider {
    private static final String DEFAULT_PROVIDER = "org.apache.johnzon.core.JsonProviderImpl";

    protected JsonProvider() {
        // no-op
    }

    public static JsonProvider provider() {
        if (System.getSecurityManager() != null) {
            return AccessController.doPrivileged(new PrivilegedAction<JsonProvider>() {
                public JsonProvider run() {
                    return doLoadProvider();
                }
            });
        }
        return doLoadProvider();
    }

    private static JsonProvider doLoadProvider() throws JsonException {
        final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        try {
            Class<? extends JsonProvider> spiClass = org.apache.servicemix.specs.locator.OsgiLocator.locate(
                    JsonProvider.class, JsonProvider.class.getName());
            if (spiClass != null) {
                return spiClass.newInstance();
            }
        } catch (final Throwable e) {
            // locator not available, try normal mode
        }

        // don't use Class.forName() to avoid to bind class to tccl if thats a classloader facade
        // so implementing a simple SPI when ProviderLocator is not here
        final String name = "META-INF/services/" + JsonProvider.class.getName();
        try {
            Enumeration<URL> configs;
            if (tccl == null) {
                configs = ClassLoader.getSystemResources(name);
            } else {
                configs = tccl.getResources(name);
            }

            if (configs.hasMoreElements()) {
                InputStream in = null;
                BufferedReader r = null;
                final List<String> names = new ArrayList<String>();
                try {
                    in = configs.nextElement().openStream();
                    r = new BufferedReader(new InputStreamReader(in, "utf-8"));
                    String l;
                    while ((l = r.readLine()) != null) {
                        if (l.startsWith("#")) {
                            continue;
                        }
                        return JsonProvider.class.cast(tccl.loadClass(l).newInstance());
                    }
                } catch (final IOException x) {
                    // no-op
                } finally {
                    try {
                        if (r != null) {
                            r.close();
                        }
                    } catch (final IOException y) {
                        // no-op
                    }
                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (final IOException y) {
                        // no-op
                    }
                }
            }
        } catch (final Exception ex) {
            // no-op
        }

        try {
            final Class<?> clazz = tccl.loadClass(DEFAULT_PROVIDER);
            return JsonProvider.class.cast(clazz.newInstance());
        } catch (final Throwable cnfe) {
            throw new JsonException(DEFAULT_PROVIDER + " not found", cnfe);
        }
    }

    public abstract JsonParser createParser(Reader reader);

    public abstract JsonParser createParser(InputStream in);

    public abstract JsonParserFactory createParserFactory(Map<String, ?> config);

    public abstract JsonGenerator createGenerator(Writer writer);

    public abstract JsonGenerator createGenerator(OutputStream out);

    public abstract JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config);

    public abstract JsonReader createReader(Reader reader);

    public abstract JsonReader createReader(InputStream in);

    public abstract JsonWriter createWriter(Writer writer);

    public abstract JsonWriter createWriter(OutputStream out);

    public abstract JsonWriterFactory createWriterFactory(Map<String, ?> config);

    public abstract JsonReaderFactory createReaderFactory(Map<String, ?> config);

    /**
     * Create an empty JsonObjectBuilder
     * @since 1.0
     */
    public abstract JsonObjectBuilder createObjectBuilder();

    /**
     * Creates a JSON object builder, initialized with the specified JsonObject.
     * @since 1.1
     */
    public JsonObjectBuilder createObjectBuilder(JsonObject jsonObject) {
        throw new UnsupportedOperationException();
    }

    /**
     * Creates a JSON object builder, initialized with the specified Map.
     * @since 1.1
     */
    public JsonObjectBuilder createObjectBuilder(Map<String, Object> map) {
        throw new UnsupportedOperationException();
    }

    public abstract JsonArrayBuilder createArrayBuilder();

    public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
        throw new UnsupportedOperationException();
    }

    public JsonArrayBuilder createArrayBuilder(Collection<?> initialData) {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a {@link JsonPointer} based on the given path string
     *
     * @since 1.1
     */
    public JsonPointer createPointer(String path) {
        throw new UnsupportedOperationException();
    }

    public abstract JsonBuilderFactory createBuilderFactory(Map<String, ?> config);


    public JsonString createValue(String value) {
        throw new UnsupportedOperationException();
    }

    public JsonNumber createValue(int value) {
        throw new UnsupportedOperationException();
    }

    public JsonNumber createValue(long value) {
        throw new UnsupportedOperationException();
    }

    public JsonNumber createValue(double value) {
        throw new UnsupportedOperationException();
    }

    public JsonNumber createValue(BigDecimal value) {
        throw new UnsupportedOperationException();
    }

    public JsonNumber createValue(BigInteger value) {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a {@link JsonPatch} as defined in
     * <a href="https://tools.ietf.org/html/rfc6902">RFC-6902</a>.
     *
     * @param array with the patch operations
     * @return the JsonPatch based on the given operations
     *
     * @see #createDiff(JsonStructure, JsonStructure)
     *
     * @since 1.1
     */
    public JsonPatch createPatch(JsonArray array) {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a {@link JsonPatch} by comparing the source to the target as defined in
     * <a href="https://tools.ietf.org/html/rfc6902">RFC-6902</a>.
     *
     * Applying this {@link JsonPatch} to the source you will give you the target.
     *
     * @see #createPatch(JsonArray)
     *
     * @since 1.1
     */
    public JsonPatch createDiff(JsonStructure source, JsonStructure target) {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a new JsonPatchBuilder
     * @since 1.1
     */
    public JsonPatchBuilder createPatchBuilder() {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a new JsonPatchBuilder from initial data.
     * @param initialData the initial patch operations
     * @since 1.1
     */
    public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
        throw new UnsupportedOperationException();
    }

    /**
     * Create a merge patch based on the given JsonValue.
     *
     * If you have the following JsonMergePatch:
     *
     * <pre>
     * {
     *   "a":"z",
     *   "c": {
     *     "f": null
     *   }
     * }
     * </pre>
     *
     * and apply it to the following JSON
     *
     * <pre>
     * {
     *   "a": "b",
     *   "c": {
     *     "d": "e",
     *     "f": "g"
     *   }
     * }
     * </pre>
     *
     * you will get the following result:
     *
     * <pre>
     * {
     *   "a": "z",
     *   "c": {
     *     "d": "e",
     *   }
     * }
     * </pre>
     *
     * @see #createMergeDiff(JsonValue, JsonValue)
     *
     * @since 1.1
     */
    public JsonMergePatch createMergePatch(JsonValue patch) {
        throw new UnsupportedOperationException();
    }


    /**
     * Create a merge patch by comparing the source to the target.
     * Applying this JsonMergePatch to the source will give you the target.
     * A MergePatch is a JsonValue as defined in http://tools.ietf.org/html/rfc7396
     *
     * If you have a JSON like
     * <pre>
     * {
     *   "a": "b",
     *   "c": {
     *     "d": "e",
     *     "f": "g"
     *   }
     * }
     * </pre>
     *
     * and comparing it with
     *
     * <pre>
     * {
     *   "a": "z",
     *   "c": {
     *     "d": "e",
     *   }
     * }
     * </pre>
     *
     * you will get the following JsonMergePatch:
     *
     * <pre>
     * {
     *   "a":"z",
     *   "c": {
     *     "f": null
     *   }
     * }
     * </pre>
     *
     * @see #createMergePatch(JsonValue)
     *
     * @since 1.1
     */
    public JsonMergePatch createMergeDiff(JsonValue source, JsonValue target) {
        throw new UnsupportedOperationException();
    }
}

