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

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.empire.commons.Attributes;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.OptionEntry;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.data.DataMode;
import org.apache.empire.data.DataType;
import org.apache.empire.db.exceptions.FieldIllegalValueException;
import org.apache.empire.db.exceptions.FieldNotNullException;
import org.apache.empire.db.exceptions.FieldValueOutOfRangeException;
import org.apache.empire.db.exceptions.FieldValueTooLongException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.InvalidPropertyException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.exceptions.PropertyReadOnlyException;
import org.apache.empire.xml.XMLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;


/**
 * This class represent one column of a table.
 * It contains all properties of this columns (e.g. the column width).
 * 
 *
 */
public class DBTableColumn extends DBColumn
{
    private final static long serialVersionUID = 1L;
    private static final Logger log = LoggerFactory.getLogger(DBTableColumn.class);
    
    // Column Information
    protected DataType  type;
    protected double    size;
    protected boolean   required;
    protected boolean   autoGenerated;
    protected boolean   readOnly;
    protected Object    defaultValue;
    protected int 		decimalScale = 0;

    /**
     * Constructs a DBTableColumn object set the specified parameters to this object.
     * 
     * @param table the table object to add the column to, set to null if you don't want it added to a table
     * @param type the type of the column e.g. integer, text, date
     * @param name the column name
     * @param size the column width
     * @param dataMode determines whether this column is optional, required or auto-generated 
     * @param defValue the object value
     */
    public DBTableColumn(DBTable table, DataType type, String name, double size, boolean required, boolean autoGenerated, Object defValue)
    {
        super(table, name);
        // check properties
        // set column properties
        this.type = type;
        this.required = required;
        this.autoGenerated = autoGenerated;
        this.readOnly = autoGenerated;
        this.defaultValue = defValue;
        // xml
        this.attributes = new Attributes();
        this.options = null;
        // size (after attributes!)
        setSize(size);
    }

    /**
     * Old constructor which will be removed in a further release.
     * @deprecated use {@link #DBTableColumn(DBTable table, DataType type, String name, double size, boolean required, boolean autoGenerated, Object defValue)} instead. 
     */
    @Deprecated
    public DBTableColumn(DBTable table, DataType type, String name, double size, DataMode dataMode, Object defValue)
    {
        this(table, type, name, size, (dataMode!=DataMode.Nullable), (dataMode==DataMode.AutoGenerated), defValue);
    }
    
    /**
     * Clone Constructor - use clone()
     */
    protected DBTableColumn(DBTable newTable, DBTableColumn other)
    {
        super(newTable, other.name);
        // Copy
        this.type = other.type;
        this.size = other.size;
        this.required = other.required;
        this.autoGenerated = other.autoGenerated;
        this.readOnly = other.readOnly;
        this.defaultValue = other.defaultValue;
        this.attributes = new Attributes();
        this.attributes.addAll(other.attributes);
        this.options = other.options;
        if (newTable != null)
        {
            newTable.addColumn(this);
        }
    }
    
    /**
     * Returns the default column value.
     * For columns of type DBDataType.AUTOINC this is assumed to be the name of a sequence
     * 
     * @return the default column value
     */
    public Object getDefaultValue()
    {
        return defaultValue;
    }

    /**
     * Sets the default column value.
     * 
     * @param defValue the default column value
     */
    public void setDefaultValue(Object defValue)
    {
        this.defaultValue = defValue;
    }
    
    /**
     * Returns the default column value. 
     * Unlike getDefaultValue this function is used when creating or adding records.
     * If the column value is DBDataType AUTOIN this function will return a new sequence value for this record
     * 
     * @param conn a valid database connection
     * @return the default column value
     */
    public Object getRecordDefaultValue(Connection conn)
    {	// Check params   
        if (rowset==null)
            return defaultValue;
        // Detect default value
        DBDatabase db = rowset.getDatabase();
        if (isAutoGenerated())
        {   // If no connection is supplied defer till later
        	if (conn==null)
        		return null; // Create Later
            // Other auto-generated values
        	DBDatabaseDriver driver = db.getDriver();
            return driver.getColumnAutoValue(db, this, conn);
        }
        // Normal value
        return defaultValue;
    }

    /**
     * Returns the data type.
     * 
     * @return the data type
     */
    @Override
    public DataType getDataType()
    {
        return type;
    }

    /**
     * Gets the the column width.
     * 
     * @return the column width
     */
    @Override
    public double getSize()
    {
        return size;
    }

    /**
     * Changes the size of the table column<BR>
     * Use for dynamic data model changes only.<BR>
     * @param size the new column size
     */
    public void setSize(double size)
    {
        // Negative size?
        if (size<0)
        {   // For Text-Columns set attribute "SINGLEBYTECHARS"
            if (getDataType().isText())
            {
                setAttribute(DBCOLATTR_SINGLEBYTECHARS, Boolean.TRUE);
            }    
            else
                throw new InvalidArgumentException("size", size);
            // Remove sign
            size = Math.abs(size);
        }
        else if (attributes!=null && attributes.contains(DBCOLATTR_SINGLEBYTECHARS))
        {   // Remove single by chars attribute
            attributes.remove(DBCOLATTR_SINGLEBYTECHARS);
        }
        // set now
        this.size = size;
        // set scale
    	if (getDataType()==DataType.DECIMAL)
    	{	// set scale from size
		    int reqPrec = (int)size;
		    this.decimalScale = ((int)(size*10)-(reqPrec*10));
    	}
    }
    
    /**
     * Returns the scale of the Decimal or 0 if the DataType is not DataType.DECIMAL.
     * @return the decimal scale
     */
    public int getDecimalScale()
    {
	    return this.decimalScale;
    }
    
    /**
     * Sets the scale of a decimal. The DataType must be set to DataType.DECIMAL otherwise an exception is thrown. 
     */
    public void setDecimalScale(int scale)
    {
    	if (getDataType()!=DataType.DECIMAL)
    		throw new NotSupportedException(this, "setDecimalScale");
    	// return scale
	    this.decimalScale = scale;
    }

    /**
     * Returns true if column is mandatory. Only for the graphic presentation.
     * 
     * @return true if column is mandatory 
     */
    @Override
    public boolean isRequired()
    {
        return this.required;
    }
    
    /**
     * Returns true if column is a numeric sequence or otherwise generated value
     * 
     * @return true if column is auto increment
     */
    @Override
    public boolean isAutoGenerated()
    {
        return this.autoGenerated;
    }
    
    /**
     * Returns true if column the column is a single byte text or character column or false otherwise
     * 
     * @return true if column is a single byte character based column
     */
    public boolean isSingleByteChars()
    {
        if (attributes==null || !attributes.contains(DBCOLATTR_SINGLEBYTECHARS))
            return false;
        // Check Attribute
        return ObjectUtils.getBoolean(attributes.get(DBCOLATTR_SINGLEBYTECHARS));
    }
    
    /**
     * sets whether this column is a single byte character or text column 
     */
    public void setSingleByteChars(boolean singleByteChars)
    {
        if (!getDataType().isText())
            throw new NotSupportedException(this, "setSingleByteChars");
        // set single byte
        setAttribute(DBCOLATTR_SINGLEBYTECHARS, singleByteChars);
    }

    /**
     * Changes the required property of the table column<BR>
     * Use for dynamic data model changes only.<BR>
     * @param required true if the column is required or false otherwise
     */
    public void setRequired(boolean required)
    {
        if (isAutoGenerated())
        {	// cannot change auto-generated columns
            throw new PropertyReadOnlyException("required"); 
        }
        else
        {	// Set DataMode
        	this.required = required;
        }
    }

    /**
     * Checks whether the column is read only.
     * 
     * @return true if the column is read only
     */
    @Override
    public boolean isReadOnly()
    {   
        return this.readOnly;
    }

    /**
     * Sets the read only attribute of the column.
     *
     * @param readOnly true if the column should be read only or false otherwise
     */
    public void setReadOnly(boolean readOnly)
    {
        this.readOnly = readOnly;
    }
    
    /**
     * sets the options from an enum class
     */
    public void setEnumOptions(Class<?> enumType)
    {
        // Enum special treatment
        log.debug("Adding enum options of type {} for column {}.", enumType.getName(), getName());            
        this.options = new Options(enumType);
        // set enumType
        setAttribute(Column.COLATTR_ENUMTYPE, enumType);
        // check length
        if (getDataType().isNumeric())
            return; // no check required
        int maxLength = (int)size;
        for (OptionEntry oe : options)
        {   // check length
            String val = oe.getValueString();
            if (val!=null && val.length()>maxLength)
                throw new InvalidPropertyException(enumType.getName(), val);
        }
    }

    /**
     * Checks whether the supplied value is valid for this column.
     * If the type of the value supplied does not match the columns
     * data type the value will be checked for compatibility. 
     * 
     * @param value the checked to check for validity
     * @return true if the value is valid or false otherwise.
     */
    @Override
    public Object validate(Object value)
    {
        // Check for NULL
        if (ObjectUtils.isEmpty(value))
        {   // Null value   
            if (isRequired())
                throw new FieldNotNullException(this);
            // Null is allowed
            return null;
        }
        // Check for Column expression
        if (value instanceof DBColumnExpr)
        {   DataType funcType = ((DBColumnExpr)value).getDataType();
            if (!type.isCompatible(funcType))
            {   // Incompatible data types
                log.info("Incompatible data types in expression for column {} using function {}!", getName(), value.toString());
                throw new FieldIllegalValueException(this, String.valueOf(value));
            }
            // allowed
            return value; 
        }
        // Check for Command expression
        if (value instanceof DBCommandExpr)
        {   DBColumnExpr[] exprList = ((DBCommandExpr)value).getSelectExprList();
            if (exprList.length!=1)
            {   // Incompatible data types
                log.info("Invalid command expression for column {} using command {}!", getName(), ((DBCommandExpr)value).getSelect());
                throw new FieldIllegalValueException(this, ((DBCommandExpr)value).getSelect());
            }
            // Compare types
            if (!type.isCompatible(exprList[0].getDataType()))
            {   // Incompatible data types
                log.info("Incompatible data types in expression for column {} using function {}!", getName(), value.toString());
                throw new FieldIllegalValueException(this, String.valueOf(value));
            }
            // allowed
            return value; 
        }
        // Is value valid
        switch (type)
        {
            case DATE:
            case DATETIME:
            case TIMESTAMP:
                // Check whether value is a valid date/time value!
                if (!(value instanceof Date) && !DBDatabase.SYSDATE.equals(value))
                {   // Parse String
                    String dateValue = value.toString();
                    if (dateValue.length()==0)
                        return null;
                    // Convert through SimpleDateFormat
                    String datePattern = StringUtils.coalesce(StringUtils.toString(getAttribute(Column.COLATTR_DATETIMEPATTERN)), "yyyy-MM-dd HH:mm:ss");
                    if ((type==DataType.DATE || dateValue.length()<=12) && datePattern.indexOf(' ')>0)
                        datePattern = datePattern.substring(0, datePattern.indexOf(' ')); // Strip off time
                    try
                    {   // Parse date time value
                        SimpleDateFormat sdFormat = new SimpleDateFormat(datePattern);
                        sdFormat.setLenient(true);
                        value = sdFormat.parse(dateValue);
                        // OK
                    } catch (ParseException e)
                    {   // Error
                        log.info("Parsing '{}' to Date ("+datePattern+") failed for column {}. Message is "+e.toString(), value, getName());
                        throw new FieldIllegalValueException(this, String.valueOf(value), e);
                    }
                }    
                break;

            case DECIMAL:
                // check enum
                if (value instanceof Enum<?>)
                {   // convert enum   
                    value = ((Enum<?>)value).ordinal();
                }
                // check number
                if (!(value instanceof java.lang.Number))
                {   try
                    {   // Convert to String and check
                        value = ObjectUtils.toDecimal(value);
                        // throws NumberFormatException if not a number!
                    } catch (NumberFormatException e)
                    {
                        log.info("Parsing '{}' to Decimal failed for column {}. Message is "+e.toString(), value, getName());
                        throw new FieldIllegalValueException(this, String.valueOf(value), e);
                    }
                }
                // validate Number
                value = validateNumber(type, (Number)value);
                break;

            case FLOAT:
                if (!(value instanceof java.lang.Number))
                {   try
                    {   // Convert to String and check
                        value = ObjectUtils.toDouble(value);
                        // throws NumberFormatException if not a number!
                    } catch (NumberFormatException e)
                    {
                        log.info("Parsing '{}' to Double failed for column {}. Message is "+e.toString(), value, getName());
                        throw new FieldIllegalValueException(this, String.valueOf(value), e);
                    }
                }
                // validate Number
                value = validateNumber(type, (Number)value);
                break;

            case INTEGER:
                // check enum
                if (value instanceof Enum<?>)
                {   // convert enum   
                    value = ((Enum<?>)value).ordinal();
                }
                // check number
                if (!(value instanceof java.lang.Number))
                {   try
                    {   // Convert to String and check
                        value = ObjectUtils.toLong(value);
                        // throws NumberFormatException if not an integer!
                    } catch (NumberFormatException e)
                    {
                        log.info("Parsing '{}' to Integer failed for column {}. Message is "+e.toString(), value, getName());
                        throw new FieldIllegalValueException(this, String.valueOf(value), e);
                    }
                }
                // validate Number
                value = validateNumber(type, (Number)value);
                break;

            case TEXT:
            case VARCHAR:
            case CHAR:
                // check enum
                if (value instanceof Enum<?>)
                {   // convert enum   
                    value = ObjectUtils.getString((Enum<?>)value);
                }
                // check length
                if (value.toString().length() > size)
                {
                    throw new FieldValueTooLongException(this);
                }
                break;
                
            default:
                if (log.isDebugEnabled())
                    log.debug("No column validation has been implemented for data type " + type);
                break;

        }
        return value;
    }
    
    protected Number validateNumber(DataType type, Number n)
    {
        // Check Range
        Object min = getAttribute(Column.COLATTR_MINVALUE);
        Object max = getAttribute(Column.COLATTR_MAXVALUE);
        if (min!=null && max!=null)
        {   // Check Range
            long minVal = ObjectUtils.getLong(min);
            long maxVal = ObjectUtils.getLong(max);
            if (n.longValue()<minVal || n.longValue()>maxVal)
            {   // Out of Range
                throw new FieldValueOutOfRangeException(this, minVal, maxVal);
            }
        }
        else if (min!=null)
        {   // Check Min Value
            long minVal = ObjectUtils.getLong(min);
            if (n.longValue()<minVal)
            {   // Out of Range
                throw new FieldValueOutOfRangeException(this, minVal, false);
            }
        }
        else if (max!=null)
        {   // Check Max Value
            long maxVal = ObjectUtils.getLong(max);
            if (n.longValue()>maxVal)
            {   // Out of Range
                throw new FieldValueOutOfRangeException(this, maxVal, true);
            }
        }
        // Check overall
        if (type==DataType.DECIMAL)
        {   // Convert to Decimal
            BigDecimal dv = ObjectUtils.toDecimal(n);
            int prec = dv.precision();
            int scale = dv.scale();
            // check precision and scale
            double size = getSize();
            int reqPrec = (int)size;
            int reqScale = getDecimalScale();
            if (scale>reqScale)
            {   // Round if scale is exceeded
                dv = dv.setScale(reqScale, RoundingMode.HALF_UP);
                prec  = dv.precision();
                scale = dv.scale();
                n = dv;
            }
            if ((prec-scale)>(reqPrec-reqScale))
            {   
                throw new FieldValueOutOfRangeException(this);
            }
        }
        return n;
    }

    /**
     * Creates a foreign key relation for this column.
     * 
     * @param target the referenced primary key column
     * @return the reference object
     */
    public DBRelation.DBReference referenceOn(DBTableColumn target)
    {
        return new DBRelation.DBReference(this, target);
    }

    /**
     * Sets field elements, default attributes and all options to
     * the specified Element object (XML tag).
     * 
     * @param parent the parent object
     * @param flags a long value
     * @return the work up Element object
     */
    @Override
    public Element addXml(Element parent, long flags)
    { // Add Field element
        Element elem = XMLUtil.addElement(parent, "column");
        elem.setAttribute("name", name);
        // set default attributes
        DBIndex primaryKey = ((DBTable) rowset).getPrimaryKey();
        if (primaryKey != null)
        {
            int keyIndex;
            if ((keyIndex = ((DBTable) rowset).getPrimaryKey().getColumnPos(this)) >= 0)
                elem.setAttribute("key", String.valueOf(keyIndex + 1));
        }
        if (size > 0)
        {
            elem.setAttribute("size", String.valueOf((int)size));
            if (getDataType()==DataType.DECIMAL)
                elem.setAttribute("decimals", String.valueOf((int)(size*10)%10));
        }
        if (isRequired())
            elem.setAttribute("mandatory", String.valueOf(Boolean.TRUE));
        // add All Attributes
        if (attributes!=null)
            attributes.addXml(elem, flags);
        // add All Options
        if (options!=null)
            options.addXml(elem, flags);
        // done
        return elem;
    }
    
    /**
     * Gets the sequence name for this table's sequence (if it has one)
     * This is derived form the default value or auto generated if no default value is set
     * @return the sequence name
     */
	public String getSequenceName()
	{
		String seqName;
		Object defValue = getDefaultValue();
		if(defValue != null)
		{
			seqName = defValue.toString();
		}
		else
		{
			if (rowset != null) 
			{
				seqName = rowset.getName() + "." + name;
			} 
			else 
			{
				seqName = name;
			}
		}
		return seqName;
	}
}