/*
 * 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
     */
    @Override
    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
	 */
    @Override
    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
     */
    @Override
    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;
   }
}
