/*
 * 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.List;
import java.util.regex.Pattern;

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.felix.cm.json.Configurations;

/**
 * Instances of this class represent a single configuration property
 * This class is not thread safe.
 */
public class PropertyDescription extends DescribableEntity {
	
	/** The property type */
	private PropertyType type;

	/** The property cardinality */
    private int cardinality;

	/** The optional variable */
    private String variable;

	/** The optional range */
	private Range range;

	/** The required includes for an array/collection (optional) */
	private String[] includes;

	/** The required excludes for an array/collection (optional) */
	private String[] excludes;

	/** The optional list of options for the value */
	private List<Option> options;
	
	/** The optional regex */
	private Pattern pattern;

	/** Required? */
	private boolean required;
    
    /** 
     * The optional default value 
     * @since 1.2
     */
    private Object defaultValue;

    /** 
     * The validation mode. 
     * @since 1.2
     */
    private Mode mode;

    /**
     * The placeholder policy
     * @since 1.3
     */
    private PlaceholderPolicy placeholderPolicy;

	/**
     * A pattern to validate values which contain substitution placeholders
     * @since 1.3
     */
	private Pattern placeholderPattern;

    /**
     * Create a new description
     */
    public PropertyDescription() {
        this.setDefaults();
    }

    void setDefaults() {
		this.setType(PropertyType.STRING);
        this.setCardinality(1);
        this.setRequired(false);
        this.setPlaceholderPolicy(PlaceholderPolicy.DEFAULT);
    }

    /**
     * Clear the object and reset to defaults
     */
    @Override
	public void clear() {
        super.clear();
        this.setDefaults();
		this.setVariable(null);
		this.setRange(null);
		this.setIncludes(null);
		this.setExcludes(null);
		this.setOptions(null);
		this.setRegex(null);
        this.setDefaultValue(null);
        this.setMode(null);
    }

	/**
	 * 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 {
			this.setVariable(this.getString(InternalConstants.KEY_VARIABLE));
			this.setCardinality(this.getInteger(InternalConstants.KEY_CARDINALITY, this.getCardinality()));
			this.setRequired(this.getBoolean(InternalConstants.KEY_REQUIRED, this.isRequired()));
			
			final String typeVal = this.getString(InternalConstants.KEY_TYPE);
			if ( typeVal != null ) {
                this.setType(PropertyType.valueOf(typeVal.toUpperCase()));				
			}
			final JsonValue rangeVal = this.getAttributes().remove(InternalConstants.KEY_RANGE);
			if ( rangeVal != null ) {
				final Range range = new Range();
				range.fromJSONObject(rangeVal.asJsonObject());
				this.setRange(range);
			}
			final JsonValue incs = this.getAttributes().remove(InternalConstants.KEY_INCLUDES);
			if ( incs != null ) {
				final List<String> list = new ArrayList<>();
				for(final JsonValue innerVal : incs.asJsonArray()) {
                    list.add(getString(innerVal));
                }
                this.setIncludes(list.toArray(new String[list.size()]));
			}
			final JsonValue excs = this.getAttributes().remove(InternalConstants.KEY_EXCLUDES);
			if ( excs != null ) {
				final List<String> list = new ArrayList<>();
				for(final JsonValue innerVal : excs.asJsonArray()) {
                    list.add(getString(innerVal));
                }
                this.setExcludes(list.toArray(new String[list.size()]));
			}
			final JsonValue opts = this.getAttributes().remove(InternalConstants.KEY_OPTIONS);
			if ( opts != null ) {
				final List<Option> list = new ArrayList<>();
				for(final JsonValue innerVal : opts.asJsonArray()) {
					final Option o = new Option();
					o.fromJSONObject(innerVal.asJsonObject());
					list.add(o);
                }
				this.setOptions(list);
			}
			this.setRegex(this.getString(InternalConstants.KEY_REGEX));
            final JsonValue dv = this.getAttributes().remove(InternalConstants.KEY_DEFAULT);
            if ( dv != null ) {
                this.setDefaultValue(Configurations.convertToObject(dv));
            }
			final String modeVal = this.getString(InternalConstants.KEY_MODE);
			if ( modeVal != null ) {
                this.setMode(Mode.valueOf(modeVal.toUpperCase()));				
			}
			final String policyVal = this.getString(InternalConstants.KEY_PLACEHOLDER_POLICY);
			if ( policyVal != null ) {
                this.setPlaceholderPolicy(PlaceholderPolicy.valueOf(policyVal.toUpperCase()));
			}
			this.setPlaceholderRegex(this.getString(InternalConstants.KEY_PLACEHOLDER_REGEX));
 		} catch (final JsonException | IllegalArgumentException e) {
            throw new IOException(e);
        }
	}
	
    /**
     * Convert this object into JSON
     *
     * @return The json object builder
     * @throws IOException If generating the JSON fails
     */
    @Override
    JsonObjectBuilder createJson() throws IOException {
		final JsonObjectBuilder objectBuilder = super.createJson();

		if ( this.getType() != null && this.getType() != PropertyType.STRING ) {
			this.setString(objectBuilder, InternalConstants.KEY_TYPE, this.getType().name());
	    }
		if ( this.getCardinality() != 1 ) {
			objectBuilder.add(InternalConstants.KEY_CARDINALITY, this.getCardinality());
		}
		if ( this.isRequired() ) {
			objectBuilder.add(InternalConstants.KEY_REQUIRED, this.isRequired());
		}
	    this.setString(objectBuilder, InternalConstants.KEY_VARIABLE, this.getVariable());
		
		if ( this.getRange() != null ) {
			objectBuilder.add(InternalConstants.KEY_RANGE, this.getRange().toJSONObject());
		}
		if ( this.getIncludes() != null && this.getIncludes().length > 0 ) {
			final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
			for(final String v : this.getIncludes()) {
				arrayBuilder.add(v);
			}
			objectBuilder.add(InternalConstants.KEY_INCLUDES, arrayBuilder);
		}
		if ( this.getExcludes() != null && this.getExcludes().length > 0 ) {
			final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
			for(final String v : this.getExcludes()) {
				arrayBuilder.add(v);
			}
			objectBuilder.add(InternalConstants.KEY_EXCLUDES, arrayBuilder);
		}
		if ( this.getOptions() != null && !this.getOptions().isEmpty()) {
			final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
            for(final Option o : this.getOptions()) {
				arrayBuilder.add(o.toJSONObject());
			}
			objectBuilder.add(InternalConstants.KEY_OPTIONS, arrayBuilder);
		}
		this.setString(objectBuilder, InternalConstants.KEY_REGEX, this.getRegex());
		if ( this.getDefaultValue() != null ) {
            objectBuilder.add(InternalConstants.KEY_DEFAULT, Configurations.convertToJsonValue(this.getDefaultValue()));
        }
        if ( this.getMode() != null ) {
            objectBuilder.add(InternalConstants.KEY_MODE, this.getMode().name());
        }
        if ( this.getPlaceholderPolicy() != PlaceholderPolicy.DEFAULT ) {
            objectBuilder.add(InternalConstants.KEY_PLACEHOLDER_POLICY, this.getPlaceholderPolicy().name());
        }
        this.setString(objectBuilder, InternalConstants.KEY_PLACEHOLDER_REGEX, this.getPlaceholderRegex());

        return objectBuilder;
	}

    /**
	 * Get the property type
	 * @return the type
	 */
	public PropertyType getType() {
		return type;
	}

	/**
	 * Set the property type
	 * @param type the type to set
	 */
	public void setType(final PropertyType type) {
		this.type = type == null ? PropertyType.STRING : type;
	}

	/**
	 * Get the cardinality
	 * @return the cardinality
	 */
	public int getCardinality() {
		return cardinality;
	}

	/**
	 * Set the cardinality
     * The default cardinality is {@code 1}. If the value is greater than zero
     * the property can contain up to that number of values.
     * If the cardinality is {@code -1} the property can hold an unlimited number
     * of values.
	 * @param value the cardinality to set
     * @throws IllegalArgumentException If the value is {@code 0} or below {@code -1}.
	 */
	public void setCardinality(final int value) {
        if ( value == 0 || value < -1 ) {
            throw new IllegalArgumentException();
        }
		this.cardinality = value;
	}

	/**
	 * Get the variable
	 * @return the variable or {@code null}
	 */
	public String getVariable() {
		return variable;
	}

	/**
	 * Set the variable
	 * @param variable the variable to set
	 */
	public void setVariable(final String variable) {
		this.variable = variable;
	}

	/**
	 * Get the range
	 * @return the range or {@code null}
	 */
	public Range getRange() {
		return range;
	}

	/**
	 * Set the range
	 * @param range the range to set
	 */
	public void setRange(final Range range) {
		this.range = range;
	}

	/**
	 * Get the includes
	 * @return the includes or {@code null}
	 */
	public String[] getIncludes() {
		return includes;
	}

	/**
	 * Set the includes
	 * @param includes the includes to set
	 */
	public void setIncludes(final String[] includes) {
		this.includes = includes;
	}

	/**
	 * Get the excludes
	 * @return the excludes or {@code null}
	 */
	public String[] getExcludes() {
		return excludes;
	}

	/**
	 * Set the excludes
	 * @param excludes the excludes to set
	 */
	public void setExcludes(final String[] excludes) {
		this.excludes = excludes;
	}

	/**
	 * Get the list of options
	 * @return the options or {@code null}
	 */
	public List<Option> getOptions() {
		return options;
	}

	/**
	 * Set the list of options
	 * @param options the options to set
	 */
	public void setOptions(final List<Option> options) {
		this.options = options;
	}

	/**
	 * Get the regex
	 * @return the regex or {@code null}
	 */
	public String getRegex() {
		return pattern == null ? null : pattern.pattern();
	}

	/**
	 * Set the regex
	 * @param regex the regex to set
     * @throws IllegalArgumentException If the pattern is not valid
	 */
	public void setRegex(final String regex) {
        if ( regex == null ) {
            this.pattern = null;
        } else {
           this.pattern = Pattern.compile(regex);
        }
	}

    /**
     * Get the regex pattern
     * @return The pattern or {@code null}
     */
    public Pattern getRegexPattern() {
        return this.pattern;
    }

	/**
	 * Is this property required?
	 * @return {@code true} if it is required
	 */
	public boolean isRequired() {
		return this.required;
	}

	/**
	 * Set whether this property is required
	 * @param flag The new value
	 */
	public void setRequired(final boolean flag) {
		this.required = flag;
	}

    /**
     * Get the optional default value.
     * @return The default value or {@code null}
     * @since 1.2
     */
    public Object getDefaultValue() {
        return this.defaultValue;
    }
    
    /**
     * Set the optional default value.
     * @param val The default value
     * @since 1.2
     */
    public void setDefaultValue(final Object val) {
        this.defaultValue = val;
    }

    /**
     * Get the validation mode.
     * @return The mode or {@code null}
     * @since 1.2
     */
    public Mode getMode() {
        return this.mode;
    }

    /**
     * Set the validation mode
     * @param value The validation mode
     * @since 1.2
     */
    public void setMode(final Mode value) {
        this.mode = value;
    }
 
    /**
     * Get the placeholder policy.
     * @return The policy
     * @since 1.3
     */
    public PlaceholderPolicy getPlaceholderPolicy() {
        return this.placeholderPolicy;
    }

    /**
     * Set the placeholder policy
     * @param policy The new policy
     * @since 1.3
     */
    public void setPlaceholderPolicy(final PlaceholderPolicy policy) {
        this.placeholderPolicy = policy == null ? PlaceholderPolicy.DEFAULT : policy;
    }

	/**
	 * Get the placeholder regex
	 * @return the placeholder regex or {@code null}
     * @since 1.3
	 */
    public String getPlaceholderRegex() {
        return placeholderPattern == null ? null : placeholderPattern.pattern();
    }

	/**
	 * Set the placeholder regex
	 * @param regex the placeholder regex to set
     * @throws IllegalArgumentException If the pattern is not valid
     * @since 1.3
	 */
    public void setPlaceholderRegex(final String regex) {
        if ( regex == null ) {
            this.placeholderPattern = null;
        } else {
            this.placeholderPattern = Pattern.compile(regex);
        }
    }

    /**
     * Get the placeholder regex pattern
     * @return The pattern or {@code null}
     * @since 1.3
     */
    public Pattern getPlaceholderRegexPattern() {
        return this.placeholderPattern;
    }
}
