/*
 * 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.sling.feature.extension.apiregions.api.artifacts;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonValue;

import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionState;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.extension.apiregions.api.config.AttributeableEntity;

/**
 * Artifact rules define additional rules for artifacts in a feature model.
 * The rules are stored as an extension in the feature model.
 * This class is not thread safe.
 */
public class ArtifactRules extends AttributeableEntity {

    /** The name of the feature model extension. */
    public static final String EXTENSION_NAME = "artifact-rules";

    /**
     * Get the artifact rules from the feature - if it exists.
     * If the rules are updated, the containing feature is left untouched.
     * {@link #setArtifactRules(Feature, ArtifactRules)} can be used to update
     * the feature.
     * @param feature The feature
     * @return The rules or {@code null}.
     * @throws IllegalArgumentException If the extension is wrongly formatted
     */
    public static ArtifactRules getArtifactRules(final Feature feature) {
        final Extension ext = feature == null ? null : feature.getExtensions().getByName(EXTENSION_NAME);
        return getArtifactRules(ext);
    }

    /**
     * Get the artifact rules from the extension - if it exists.
     * If the rules are updated, the containing feature is left untouched.
     * {@link #setArtifactRules(Feature, ArtifactRules)} can be used to update
     * the feature.
     * @param ext The extension
     * @return The rules or {@code null} if the extension is {@code null}.
     * @throws IllegalArgumentException If the extension is wrongly formatted
     */
    public static ArtifactRules getArtifactRules(final Extension ext) {
        if ( ext == null ) {
            return null;
        }
        if ( ext.getType() != ExtensionType.JSON ) {
            throw new IllegalArgumentException("Extension " + ext.getName() + " must have JSON type");
        }
        try {
            final ArtifactRules result = new ArtifactRules();
            result.fromJSONObject(ext.getJSONStructure().asJsonObject());
            return result;
        } catch ( final IOException ioe) {
            throw new IllegalArgumentException(ioe.getMessage(), ioe);
        }
    }

    /**
     * Set the rules as an extension to the feature
     * @param feature The feature
     * @param rules The rules. If {@code null} the extension will be removed.
     * @throws IllegalStateException If the feature has already an extension of a wrong type
     * @throws IllegalArgumentException If the rules can't be serialized to JSON
     */
    public static void setArtifactRules(final Feature feature, final ArtifactRules rules) {
        Extension ext = feature.getExtensions().getByName(EXTENSION_NAME);
        if ( rules == null ) {
            if ( ext != null ) {
                feature.getExtensions().remove(ext);
            }
        } else {
            if ( ext == null ) {
                ext = new Extension(ExtensionType.JSON, EXTENSION_NAME, ExtensionState.OPTIONAL);
                feature.getExtensions().add(ext);
            }
            try {
                ext.setJSONStructure(rules.toJSONObject());
            } catch ( final IOException ioe) {
                throw new IllegalArgumentException(ioe);
            }
        }
    }

    /** The validation mode */
    private Mode mode;

    /** The version rules for bundles */
    private final List<VersionRule> bundleVersionRules = new ArrayList<>();

    /** The version rules for artifacts */
    private final List<VersionRule> artifactVersionRules = new ArrayList<>();

    /**
     * Create a new rules object
     */
    public ArtifactRules() {
        this.setDefaults();
    }

    @Override
    protected void setDefaults() {
        super.setDefaults();
        this.setMode(Mode.STRICT);
    }

    /**
     * Clear the object and reset to defaults
     */
    @Override
    public void clear() {
        super.clear();
        this.getBundleVersionRules().clear();
        this.getArtifactVersionRules().clear();
    }

    /**
     * Convert this object into JSON
     *
     * @return The json object builder
     * @throws IOException If generating the JSON fails
     */
    @Override
    public JsonObjectBuilder createJson() throws IOException {
        final JsonObjectBuilder objBuilder = super.createJson();
        if ( this.getMode() != Mode.STRICT ) {
            objBuilder.add(InternalConstants.KEY_MODE, this.getMode().name());
        }

        if ( !this.getBundleVersionRules().isEmpty() ) {
            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
            for(final VersionRule rule : this.getBundleVersionRules()) {
                arrayBuilder.add(rule.createJson());
            }
            objBuilder.add(InternalConstants.KEY_BUNDLE_VERSION_RULES, arrayBuilder);
        }

        if ( !this.getArtifactVersionRules().isEmpty() ) {
            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
            for(final VersionRule rule : this.getArtifactVersionRules()) {
                arrayBuilder.add(rule.createJson());
            }
            objBuilder.add(InternalConstants.KEY_ARTIFACT_VERSION_RULES, arrayBuilder);
        }

        return objBuilder;
    }

    /**
	 * Extract the metadata from the JSON object.
	 * This method first calls {@link #clear()}.
     *
	 * @param jsonObj The JSON Object
	 * @throws IOException If JSON parsing fails
	 */
    @Override
    public void fromJSONObject(final JsonObject jsonObj) throws IOException {
        super.fromJSONObject(jsonObj);
        try {
			final String modeVal = this.getString(InternalConstants.KEY_MODE);
			if ( modeVal != null ) {
                this.setMode(Mode.valueOf(modeVal.toUpperCase()));
			}

            JsonValue val = this.getAttributes().remove(InternalConstants.KEY_BUNDLE_VERSION_RULES);
            if ( val != null ) {
                for(final JsonValue innerVal : val.asJsonArray()) {
                    final VersionRule rule = new VersionRule();
                    rule.fromJSONObject(innerVal.asJsonObject());
                    this.getBundleVersionRules().add(rule);
                }
            }

            val = this.getAttributes().remove(InternalConstants.KEY_ARTIFACT_VERSION_RULES);
            if ( val != null ) {
                for(final JsonValue innerVal : val.asJsonArray()) {
                    final VersionRule rule = new VersionRule();
                    rule.fromJSONObject(innerVal.asJsonObject());
                    this.getArtifactVersionRules().add(rule);
                }
            }
        } catch (final JsonException | IllegalArgumentException e) {
            throw new IOException(e);
        }
    }

    /**
     * Get the validation mode.
     * The default is {@link Mode#STRICT}
     * @return The mode
     */
    public Mode getMode() {
        return this.mode;
    }

    /**
     * Set the validation mode
     * @param value The validation mode
     */
    public void setMode(final Mode value) {
        this.mode = value == null ? Mode.STRICT : value;
    }

    /**
     * Return the list of version rules for bundles. The returned list is mutable.
     * @return The list of rules, might be empty.
     */
    public List<VersionRule> getBundleVersionRules() {
        return this.bundleVersionRules;
    }

    /**
     * Return the list of version rules for artifacts. The returned list is mutable.
     * @return the list of rules, might be empty.
     */
    public List<VersionRule> getArtifactVersionRules() {
        return artifactVersionRules;
    }
}
