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

import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.extension.apiregions.api.config.Mode;
import org.apache.sling.feature.extension.apiregions.api.config.Option;
import org.apache.sling.feature.extension.apiregions.api.config.PlaceholderPolicy;
import org.apache.sling.feature.extension.apiregions.api.config.PropertyDescription;
import org.apache.sling.feature.extension.apiregions.api.config.PropertyType;
import org.apache.sling.feature.extension.apiregions.api.config.Region;

/**
 * Validate a configuration property or framework property
 */
public class PropertyValidator {
    
    private boolean liveValues = false;

    /**
     * Are live values validated?
     * @return {@code true} if live values are validated
     * @since 1.4
     */
    public boolean isLiveValues() {
        return liveValues;
    }

    /**
     * Set whether live values are validated.
     * @param value Flag for validating live values
     * @since 1.4
     */
    public void setLiveValues(final boolean value) {
        this.liveValues = value;
    }

	/**
	 * Validate the value against the property definition
     * @param value The value to validate
     * @param desc The property description
	 * @return A property validation result
	 */
	public PropertyValidationResult validate(final Object value, final PropertyDescription desc) {
        return this.validate(value, desc, Mode.STRICT);
    }

    /**
	 * Validate the value against the property definition
     * @param value The value to validate
     * @param desc The property description
     * @param mode Optional validation mode - this mode is used if the description does not define a mode. Defaults to {@link Mode#STRICT}.
	 * @return A property validation result
     * @since 1.2.0
	 */
	public PropertyValidationResult validate(final Object value, final PropertyDescription desc, final Mode mode) {
        final Context context = new Context();
        context.description = desc;
        context.validationMode = desc.getMode() != null ? desc.getMode() : (mode != null ? mode : Mode.STRICT);

        if ( value == null ) {
            if ( desc.isRequired() ) {
                setResult(context, "No value provided");
            }
		} else {
			final List<Object> values;
			if ( value.getClass().isArray() ) {
				// array
				values = new ArrayList<>();
                for(int i=0;i<Array.getLength(value);i++) {
					values.add(Array.get(value, i));
				}
			} else if ( value instanceof Collection ) { 
				// collection
				values = new ArrayList<>();
				final Collection<?> c = (Collection<?>)value;
				for(final Object o : c) {
					values.add(o);
				}
			} else {
				// single value
				values = null;
				validateValue(context, value);
			}

			if ( values != null ) {
                // array or collection
                for(final Object val : values) {
                    validateValue(context, val);
                }
                validateList(context, values);
            }
            
            if ( desc.getDeprecated() != null ) {
                context.result.getWarnings().add(desc.getDeprecated());
            }

            // set postfix to the message if since or enforce-on are set
            String postfixMsg = "";
            if ( desc.getSince() != null ) {
                postfixMsg = postfixMsg.concat(". Since : ").concat(desc.getSince());
            }
            if ( desc.getEnforceOn() != null ) {
                postfixMsg = postfixMsg.concat(". Enforced on : ").concat(desc.getEnforceOn());
            }
            for (int i = 0; i < context.result.getWarnings().size(); i++) {
                context.result.getWarnings().set(i, context.result.getWarnings().get(i) + postfixMsg);
            }
            for (int i = 0; i < context.result.getErrors().size(); i++) {
                context.result.getErrors().set(i, context.result.getErrors().get(i) + postfixMsg);
            }
		}
		return context.result;
	}

    void setResult(final Context context, final String msg) {
        setResult(context.result, context.description.getDefaultValue(), context.validationMode, msg);
    }

    static void setResult(final PropertyValidationResult result, final Object defaultValue, final Mode validationMode, final String msg) {
        if ( validationMode == Mode.STRICT ) {
            result.getErrors().add(msg);
        } else if ( validationMode == Mode.LENIENT || validationMode == Mode.DEFINITIVE ) {
            result.getWarnings().add(msg);
        }
        if ( validationMode == Mode.DEFINITIVE || validationMode == Mode.SILENT_DEFINITIVE ) {
            result.setUseDefaultValue(true);
            result.setDefaultValue(defaultValue);
        }
    }
    
    /**
     * Validate a multi value
     * @param prop The property description
     * @param values The values
     * @param messages The messages to record errors
     */
    void validateList(final Context context, final List<Object> values) {
        if ( context.description.getCardinality() > 0 && values.size() > context.description.getCardinality() ) {
            setResult(context, "Array/collection contains too many elements, only " + context.description.getCardinality() + " allowed");
        }
        if ( context.description.getIncludes() != null ) {
            for(final String inc : context.description.getIncludes()) {
                boolean found = false;
                for(final Object val : values) {
                    if ( inc.equals(val.toString())) {
                        found = true;
                        break;
                    }
                }
                if ( !found ) {
                    setResult(context, "Required included value " + inc + " not found");
                }
            }
        }
        if ( context.description.getExcludes() != null ) {
            for(final String exc : context.description.getExcludes()) {
                boolean found = false;
                for(final Object val : values) {
                    if ( exc.equals(val.toString())) {
                        found = true;
                        break;
                    }
                }
                if ( found ) {
                    setResult(context, "Required excluded value " + exc + " found");
                }
            }
        }
    }

    private static final List<String> PLACEHOLDERS = Arrays.asList("$[env:", "$[secret:", "$[prop:");

	void validateValue(final Context context, final Object value) {
		if ( value != null ) {
            // check for placeholder
            boolean hasPlaceholder = false;
            if ( value instanceof String ) {
                final String strVal = (String)value;
                for(final String p : PLACEHOLDERS) {
                    if ( strVal.contains(p) ) {
                        hasPlaceholder = true;
                        break;
                    }
                }
            }
            if ( !hasPlaceholder ) {
                switch ( context.description.getType() ) {
                    case BOOLEAN : validateBoolean(context, value);
                                break;
                    case BYTE : validateByte(context, value);
                                break;
                    case CHARACTER : validateCharacter(context, value);
                                break;
                    case DOUBLE : validateDouble(context, value); 
                                break;
                    case FLOAT : validateFloat(context, value); 
                                break;
                    case INTEGER : validateInteger(context, value);
                                break;
                    case LONG : validateLong(context, value);
                                break;
                    case SHORT : validateShort(context, value);
                                break;
                    case STRING : validateRequired(context, value);
                                break;
                    case EMAIL : validateEmail(context, value); 
                                break;
                    case PASSWORD : validatePassword(context, value, false);
                                break;
                    case URL : validateURL(context, value);
                            break;
                    case PATH : validatePath(context, value);
                                break;
                    default : context.result.getErrors().add("Unable to validate value - unknown property type : " + context.description.getType());
                }
                validateRegex(context, context.description.getRegexPattern(), value);
                validateOptions(context, value);
                if ( context.description.getType() != PropertyType.PASSWORD ) {
                    validatePlaceholderPolicy(context, value, false);              
                }
            } else {
                // placeholder is present
                if ( context.description.getType() == PropertyType.PASSWORD ) {
                    validatePassword(context, value, true);
                } else if ( context.description.getType() == PropertyType.STRING ) {
                    validateRegex(context, context.description.getPlaceholderRegexPattern(), value);

                    // we mark the result as skipped if a regex or options are set or if a value is marked as required.
                    if ( context.description.getRegex() != null || context.description.getOptions() != null || context.description.isRequired() ) {
                        context.result.markSkipped();
                    }
                } else {
                    context.result.markSkipped();
                }
                if ( context.description.getType() != PropertyType.PASSWORD ) {
                    validatePlaceholderPolicy(context, value, true);              
                }
            }
        } else {
			setResult(context, "Null value provided for validation");
		}
	}
	
	void validateRequired(final Context context, final Object value) {
        if ( context.description.isRequired() ) {
            final String val = value.toString();
            if ( val.isEmpty() ) {
                setResult(context, "Value is required");
            }
        }
    }

    void validateBoolean(final Context context, final Object value) {
        if ( ! (value instanceof Boolean) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				if ( ! v.equalsIgnoreCase("true") && !v.equalsIgnoreCase("false") ) {
                    setResult(context, "Boolean value must either be true or false, but not " + value);
				}
			} else {
				setResult(context, "Boolean value must either be of type Boolean or String : " + value);
			}
		}
	}

	void validateByte(final Context context, final Object value) {
        if ( ! (value instanceof Byte) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Byte.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Byte : " + value);
                }
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).byteValue());            
			} else {
				setResult(context, "Byte value must either be of type Byte or String : " + value);
			}
		} else {
			validateRange(context, (Byte)value);
		}
	}

	void validateShort(final Context context, final Object value) {
        if ( ! (value instanceof Short) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Short.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Short : " + value);
				}
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).shortValue());            
			} else {
				setResult(context, "Short value must either be of type Short or String : " + value);
			}
		} else {
			validateRange(context, (Short)value);
		}
	}

	void validateInteger(final Context context, final Object value) {
        if ( ! (value instanceof Integer) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Integer.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Integer : " + value);
				}
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).intValue());            
			} else {
				setResult(context, "Integer value must either be of type Integer or String : " + value);
			}
		} else {
			validateRange(context, (Integer)value);
		}
	}

	void validateLong(final Context context, final Object value) {
        if ( ! (value instanceof Long) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Long.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Long : " + value);
				}
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).longValue());            
			} else {
				setResult(context, "Long value must either be of type Long or String : " + value);
			}
		} else {
			validateRange(context, (Long)value);
		}
	}

	void validateFloat(final Context context, final Object value) {
        if ( ! (value instanceof Float) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Float.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Float : " + value);
				}
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).floatValue());            
			} else {
				setResult(context, "Float value must either be of type Float or String : " + value);
			}
		} else {
			validateRange(context, (Float)value);
		}
	}

	void validateDouble(final Context context, final Object value) {
        if ( ! (value instanceof Double) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				try {
					validateRange(context, Double.valueOf(v));
				} catch ( final NumberFormatException nfe ) {
                    setResult(context, "Value is not a valid Double : " + value);
				}
            } else if ( value instanceof Number ) {
                validateRange(context, ((Number)value).doubleValue());            
			} else {
				setResult(context, "Double value must either be of type Double or String : " + value);
			}
		} else {
			validateRange(context, (Double)value);
		}
	}

	void validateCharacter(final Context context, final Object value) {
        if ( ! (value instanceof Character) ) {
			if ( value instanceof String ) {
				final String v = (String)value;
				if ( v.length() > 1 ) {
                    setResult(context, "Value is not a valid Character : " + value);
				}
			} else {
				setResult(context, "Character value must either be of type Character or String : " + value);
			}
		}
	}

	void validateURL(final Context context, final Object value) {
		final String val = value.toString();
		try {
			new URL(val);
		} catch ( final MalformedURLException mue) {
			setResult(context, "Value is not a valid URL : " + val);
		}
	}

	void validateEmail(final Context context, final Object value) {
		final String val = value.toString();
		// poor man's validation (should probably use InternetAddress)
		if ( !val.contains("@") ) {
			setResult(context, "Not a valid email address " + val);
		}
	}

	void validatePassword(final Context context, final Object value, final boolean hasPlaceholder) {
        if ( !this.isLiveValues() && !hasPlaceholder && context.description.getPlaceholderPolicy() != PlaceholderPolicy.DENY ) {
            setResult(context, "Value for a password must use a placeholder");
        }
	}

	void validatePath(final Context context, final Object value) {
		final String val = value.toString();
		// poor man's validation 
		if ( !val.startsWith("/") ) {
			setResult(context, "Not a valid path " + val);
		}
	}

    void validateRange(final Context context, final Number value) {
	    if ( context.description.getRange() != null ) {
            if ( context.description.getRange().getMin() != null ) {
                if ( value instanceof Float || value instanceof Double ) {
                    final double min = context.description.getRange().getMin().doubleValue();
                    if ( value.doubleValue() < min ) {
                            setResult(context, "Value " + value + " is too low; should not be lower than " + context.description.getRange().getMin());
                    }    
                } else {
                    final long min = context.description.getRange().getMin().longValue();
                    if ( value.longValue() < min ) {
                        setResult(context, "Value " + value + " is too low; should not be lower than " + context.description.getRange().getMin());
                    }    
                }
            }
            if ( context.description.getRange().getMax() != null ) {
                if ( value instanceof Float || value instanceof Double ) {
                    final double max = context.description.getRange().getMax().doubleValue();
                    if ( value.doubleValue() > max ) {
                        setResult(context, "Value " + value + " is too high; should not be higher than " + context.description.getRange().getMax());
                    }    
                } else {
                    final long max = context.description.getRange().getMax().longValue();
                    if ( value.longValue() > max ) {
                        setResult(context, "Value " + value + " is too high; should not be higher than " + context.description.getRange().getMax());
                    }    
                }
            }
		}
	}

    void validateRegex(final Context context, final Pattern pattern, final Object value) {
        if ( pattern != null ) {
            if ( !pattern.matcher(value.toString()).matches() ) {
                setResult(context, "Value " + value + " does not match regex " + pattern.pattern());
            }
        }
    }

    void validateOptions(final Context context, final Object value) {
        if ( context.description.getOptions() != null ) {
            boolean found = false;
            for(final Option opt : context.description.getOptions()) {
                if ( opt.getValue().equals(value.toString() ) ) {
                    found = true; 
                }
            }
            if ( !found ) {
                setResult(context, "Value " + value + " does not match provided options");
            }
        }
    }

    void validatePlaceholderPolicy(final Context context, final Object value, final boolean hasPlaceholder) {
        // only check policy if no live values
        if ( !this.isLiveValues() ) {
            // for policy default and allow nothing needs to be validated
            if ( context.description.getPlaceholderPolicy() == PlaceholderPolicy.DENY && hasPlaceholder ) {
                setResult(context, "Placeholder in value is not allowed");
            }  else if ( context.description.getPlaceholderPolicy() == PlaceholderPolicy.REQUIRE && !hasPlaceholder ) {
                setResult(context, "Value must use a placeholder");
            }
        } 
    }         

    static final class Context {

        public final PropertyValidationResult result = new PropertyValidationResult();

        public PropertyDescription description;

        public Mode validationMode;
    }
}
