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

// Java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Set;

import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.db.exceptions.DatabaseNotOpenException;
import org.apache.empire.db.expr.set.DBSetExpr;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.exceptions.ObjectNotValidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;


/**
 * This is the base class for all database columns that have a physical representation.
 * i.e. either table or view columns (DBTableColumn oder DBViewColumn)
 * <p>
 * The column object describes a database column and thus provides metadata.
 * Other non data model specific metadata may be added through attributes.
 *
 * @see org.apache.empire.db.DBTableColumn
 * @see org.apache.empire.db.DBView.DBViewColumn
 *
 *
 */
public abstract class DBColumn extends DBColumnExpr
    implements Column
{
    private final static long serialVersionUID = 1L;
  
    private static final Logger log = LoggerFactory.getLogger(DBColumn.class);
    
    /**
     * Read only column (Boolean)
     */
    // private static final String DBCOLATTR_READONLY  = "readonly";
    
    /**
     * Read only column (Boolean)
     */
    public static final String DBCOLATTR_SINGLEBYTECHARS  = "singleByteChars";

    // basic data
    protected final transient DBRowSet rowset;
    protected final String     name;
    protected String           comment;

    private Boolean quoteName = null;
    
    /**
     * Constructs a DBColumn object and set the specified parameters to this object.
     *
     * @param rowset the rowset (i.e. Table or View) that this column belongs to
     * @param name the column name
     */
    protected DBColumn(DBRowSet rowset, String name)
    {
        this.rowset = rowset;
        this.name = name;
        this.comment = null;
    }

    /**
     * Gets an identifier for this RowSet Object
     * @return the rowset identifier
     */
    public String getId()
    {
        return rowset.getId()+"."+name;
    }

    /**
     * returns a rowset by its identifier
     * @param columnId the id of the column
     * @return the DBColumn object
     */
    public static DBColumn findById(String columnId)
    {
        int i = columnId.lastIndexOf('.');
        if (i<0)
            throw new InvalidArgumentException("columnId", columnId);
        // rowset suchen
        String rsid = columnId.substring(0, i);
        DBRowSet rset = DBRowSet.findById(rsid);
        // column suchen
        String colname = columnId.substring(i+1);
        DBColumn col = rset.getColumn(colname);
        if (col==null)
            throw new ItemNotFoundException(columnId);
        return col;
    }
    
    /**
     * Custom serialization for transient rowset.
     */
    private void writeObject(ObjectOutputStream strm) throws IOException 
    {
        if (rowset==null)
        {   // No rowset
            strm.writeObject("");
            strm.defaultWriteObject();
            return;
        }
        // write dbid and rowset-name
        String dbid   = rowset.getDatabase().getId(); 
        String rsname = rowset.getName(); 
        strm.writeObject(dbid);
        strm.writeObject(rsname);
        if (log.isDebugEnabled())
            log.debug("Serialization: writing DBColumn "+dbid+"."+rsname);
        strm.defaultWriteObject();
    }

    /**
     * Custom serialization for transient rowset.
     */
    private void readObject(ObjectInputStream strm) throws IOException, ClassNotFoundException, 
        SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
    {
        String dbid = String.valueOf(strm.readObject());
        if (StringUtils.isNotEmpty(dbid))
        {   // Find Rowset
            String rsname = String.valueOf(strm.readObject());
            if (log.isDebugEnabled())
                log.debug("Serialization: reading DBColumn "+dbid+"."+rsname);
            // find database
            DBDatabase db = DBDatabase.findById(dbid);
            if (db==null)
                throw new ClassNotFoundException(dbid);
            // find database
            DBRowSet srs = db.getRowSet(rsname);
            if (srs==null)
                throw new ClassNotFoundException(dbid+"."+rsname);
            // set final field
            Field f = DBColumn.class.getDeclaredField("rowset");
            f.setAccessible(true);
            f.set(this, srs);
            f.setAccessible(false);
        }
        // read the rest
        strm.defaultReadObject();
    }

    @Override
    public boolean equals(Object other)
    {
        if (other==this)
            return true;
        if (rowset==null)
            return super.equals(other);
        if (other instanceof DBColumn)
        {   // Rowset and name must match
            DBColumn c = (DBColumn) other;
            if (rowset.equals(c.getRowSet())==false)
                return false;
            // check for equal names
            return StringUtils.compareEqual(name, c.getName(), true);
        }
        return false;
    }
    
    @Override
    public int hashCode()
    {
    	if (rowset==null || name==null)
    		return super.hashCode();
    	// rowset and name
    	return rowset.hashCode()+name.hashCode();
    }
     
    /**
     * Returns the size of the column.
     *
     * @return Returns the size of the column
     */
    @Override
    public abstract double getSize();

    /**
     * Returns true if the column is required.
     *
     * @return Returns true if the column is required
     */
    @Override
    public abstract boolean isRequired();
    
    /**
     * Returns true if column is a columns value is an automatically generated value
     * 
     * @return true if column is auto-generated
     */
    @Override
    public abstract boolean isAutoGenerated();

    /**
     * Returns true if the column is read-only.
     *
     * @return Returns true if the column is read-only
     */
    @Override
    public abstract boolean isReadOnly();

    /**
     * Checks if the given value is a valid value for this column 
     * If not, an exception is thrown
     */
    @Override
    public abstract Object validate(Object value);
    
    /**
     * @deprecated use validate() instead 
     */
    @Deprecated
    public final void checkValue(Object value)
    {
        validate(value);
    }
    
    @Override
    public abstract Element addXml(Element parent, long flags);

    /**
     * @return the current DBDatabase object
     */
    @Override
    public DBDatabase getDatabase()
    {
        return (rowset!=null ? rowset.getDatabase() : null);
    }

    /**
     * @see org.apache.empire.db.DBExpr#addReferencedColumns(Set)
     */
    @Override
    public void addReferencedColumns(Set<DBColumn> list)
    {
        list.add(this);
    }

    /**
     * Adds the colunm name to the SQL-Command. <br>
     * This can be either a qualified or unqualified name depending on the context.
     *
     * @param buf the SQL statment
     * @param context the current SQL-Command context
     */
    @Override
    public void addSQL(StringBuilder buf, long context)
    { 
        // Append rowset alias
        if ((context & CTX_FULLNAME) != 0)
        {   // Fully Qualified Name
            buf.append(rowset.getAlias());
            buf.append(".");
        }
        // Append the name
        DBDatabaseDriver driver = getDatabase().getDriver();
        if (driver==null)
        	throw new DatabaseNotOpenException(getDatabase());
        if (quoteName==null)
            quoteName = driver.detectQuoteName(name);
        // Append the name
        driver.appendElementName(buf, name, quoteName.booleanValue());
    }

    /**
     * Returns this object.
     *
     * @return this object
     */
    @Override
    public DBColumn getUpdateColumn()
    {
        return this;
    }

    /**
     * Always returns false since DBColumns cannot be aggregates.
     *
     * @return false
     */
    @Override
    public boolean isAggregate()
    {
        return false;
    }

    /**
     * Returns DBTable, DBQuery or DBView object.
     *
     * @return the DBTable, DBQuery or DBView object
     */
    public DBRowSet getRowSet()
    {
        return rowset;
    }

    /**
     * Returns the column name.
     *
     * @return the column name
     */
    @Override
    public String getName()
    {
        return name;
    }

    /**
     * Returns the full qualified column name.
     *
     * @return the full qualified column name
     */
    public String getFullName()
    {
        if (rowset==null)
            throw new ObjectNotValidException(this);
        return rowset.getFullName()+"."+name;
    }

    /**
     * returns the qualified alias name for this column
     */
    public String getAlias()
    {
        if (rowset==null)
            throw new ObjectNotValidException(this);
        String rsName = rowset.getName();
        if (StringUtils.isEmpty(rsName))
            return name;
        return rsName + "_" + name;
    }

    /**
     * returns an expression that renames the column with its alias name
     */
    public DBColumnExpr qualified()
    {
        return this.as(getAlias());
    }

    /**
     *  @see DBColumnExpr#getAttribute(String)
     */
    @Override
    public Object getAttribute(String name)
    {
        return (attributes != null ? attributes.get(name) : null);
    }

    /**
     *  @see DBColumnExpr#getOptions()
     */
    @Override
    public Options getOptions()
    {
        return options;
    }

    /**
     * Returns true if an enum type has been set for this column
     * <P>
     * @return eturns true if an enum type has been set for this column
     */
    public final boolean isEnum()
    {
        return (getEnumType()!=null);
    }

    /**
     * Returns the enum type for this column
     * <P>
     * @return the enum type
     */
    @Override
    @SuppressWarnings("unchecked")
    public Class<Enum<?>> getEnumType()
    {
        return (attributes!=null ? (Class<Enum<?>>)getAttribute(COLATTR_ENUMTYPE) : null);
    }

    /**
     * Creates and returns a sql-expression that maps enum values by name or ordinal to their string representation 
     * 
     * @return a DBDecodeExpr object
     */
    public DBColumnExpr decodeEnum()
    {
        return super.decodeEnum(getEnumType(), null);
    }

    /**
     * Creates and returns a sql-expression that maps enum values from name to ordinal
     * 
     * @return a DBDecodeExpr object
     */
    public DBColumnExpr decodeSort(boolean defaultToEnd)
    {
        if (getDataType().isNumeric())
        {
            log.warn("Unnecessary decode for numeric column");
            return this;
        }
        return super.decodeSort(getEnumType(), defaultToEnd);
    }
    
    /**
     * Creates and returns a new DBSetExpr object.
     *
     * @see org.apache.empire.db.expr.set.DBSetExpr
     * @param value the Object value
     * @return the new DBSetExpr object
     */
    public DBSetExpr to(Object value)
    {
        return new DBSetExpr(this, value);
    }

    /**
     * Override the toString method.
     *
     * @return the table name and the column name (e.g. CUSTOMER.ID)
     */
    @Override
    public String toString()
    {
        if (rowset==null)
            return name;
        return rowset.getName()+"."+name;
    }

    /**
     * Returns a comment describing the column in the data scheme.
     *
     * @return Returns the comment.
     */
    public String getComment()
    {
        return comment;
    }

    /**
     * Sets a comment describing the current column.
     *
     * @param comment the column comment
     */
    public void setComment(String comment)
    {
        this.comment = comment;
    }
    
}