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

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

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

/**
 * Description of an OSGi factory configuration
 */
public class FactoryConfigurationDescription extends ConfigurableEntity {
    
    private final Set<Operation> operations = new HashSet<>();

    private final List<String> internalNames = new ArrayList<>();

    public FactoryConfigurationDescription() {
        this.setDefaults();
    }

    void setDefaults() {
        this.getOperations().add(Operation.CREATE);
        this.getOperations().add(Operation.UPDATE);
    }
    
    /**
     * Clear the object and set the defaults
     */
    public void clear() {
        super.clear();
        this.setDefaults();
        this.internalNames.clear();
    }

	/**
	 * Extract the metadata from the JSON object.
	 * This method first calls {@link #clear()}
     *
	 * @param jsonObj The JSON Object
	 * @throws IOException If JSON parsing fails
	 */
    public void fromJSONObject(final JsonObject jsonObj) throws IOException {
        super.fromJSONObject(jsonObj);
        try {
            JsonValue val;
            val = this.getAttributes().remove(InternalConstants.KEY_OPERATIONS);
            if ( val != null ) {
                this.getOperations().clear();
                for(final JsonValue innerVal : val.asJsonArray()) {
                    final String v = getString(innerVal).toUpperCase();
                    this.getOperations().add(Operation.valueOf(v));
                }
                if ( this.getOperations().isEmpty() ) {
                    throw new IOException("Operations must not be empty");
                }
            }
            
            val = this.getAttributes().remove(InternalConstants.KEY_INTERNAL_NAMES);
            if ( val != null ) {
                for(final JsonValue innerVal : val.asJsonArray()) {
                    this.getInternalNames().add(getString(innerVal));
                }
            }

		} catch (final JsonException | IllegalArgumentException e) {
            throw new IOException(e);
        }
    }

   /**
    * Get the operations
	 * @return Mutable set of operations
	 */
	public Set<Operation> getOperations() {
		return operations;
	}

	/**
     * Get the internal factory configuration name
	 * @return Mutable list of internal names
	 */
	public List<String> getInternalNames() {
		return internalNames;
	}

   /**
     * Convert this object into JSON
     *
     * @return The json object builder
     * @throws IOException If generating the JSON fails
     */
    JsonObjectBuilder createJson() throws IOException {
		final JsonObjectBuilder objBuilder = super.createJson();
		
		if ( !this.getOperations().isEmpty() && this.getOperations().size() != 2 ) {
            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
            for(final Operation op : this.getOperations()) {
                arrayBuilder.add(op.name());
            }
			objBuilder.add(InternalConstants.KEY_OPERATIONS, arrayBuilder);
		}
		if ( !this.getInternalNames().isEmpty() ) {
            final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
            for(final String n : this.getInternalNames()) {
                arrayBuilder.add(n);
            }
			objBuilder.add(InternalConstants.KEY_INTERNAL_NAMES, arrayBuilder);
		}
		return objBuilder;
   }
}
