/*
 * 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.util.Collections;
import java.util.Set;

import org.apache.empire.commons.Attributes;
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.dbms.DBMSHandler;
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
{
    // *Deprecated* private static final 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 DBRowSet  rowset; /* transient */
    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 getIdentifier()
    {
        return rowset.getIdentifier()+"."+name;
    }

    /**
     * returns a rowset by its identifier
     * @param columnId the id of the column
     * @return the DBColumn object
    public static DBColumn findByIdentifier(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.findByIdentifier(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 
    {   // RowSet
        strm.writeObject(rowset.getDatabase().getIdentifier());
        strm.writeObject(rowset.getName());
        // write default
        strm.defaultWriteObject();
    }

    private void readObject(ObjectInputStream strm) throws IOException, ClassNotFoundException 
    {
        String dbid = String.valueOf(strm.readObject());
        String rsid = String.valueOf(strm.readObject());
        // find database
        DBDatabase dbo = DBDatabase.findByIdentifier(dbid);
        if (dbo==null)
            throw new ClassNotFoundException(dbid);
        // find rowset
        DBRowSet rso = dbo.getRowSet(rsid);
        if (rso==null)
            throw new ClassNotFoundException(dbid+"."+rsid);
        // set final field
        ClassUtils.setPrivateFieldValue(DBColumn.class, this, "rowset", rso);
        // 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 validateValue(Object value);

    /**
     * Appends column meta information to the parent element
     */
    @Override
    public abstract Element addXml(Element parent, long flags);

    /**
     * @return the current DBDatabase object
     */
    @SuppressWarnings("unchecked")
    @Override
    public final 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
        DBMSHandler dbms = getDatabase().getDbms();
        if (dbms==null)
        	throw new DatabaseNotOpenException(getDatabase());
        // Append the name
        dbms.appendObjectName(buf, name, quoteName);
    }

    /**
     * Returns itself as the source column.
     */
    @Override
    public DBColumn getSourceColumn()
    {
        return this;
    }

    /**
     * Returns itself as the update column.
     */
    @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.getEntityName();
        if (StringUtils.isEmpty(rsName))
            return name;
        return rsName + "_" + name;
    }

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

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

    /**
     * Returns all metadata attributes.
     * @return set of metadata attributes
     */
    @Override
    @SuppressWarnings("unchecked")
    public Set<Attributes.Attribute> getAttributes()
    {
        return (attributes!=null ? Collections.unmodifiableSet(attributes)
                                 : Collections.EMPTY_SET);
    }

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

    /**
     * Returns true if an enum type has been set for this column
     * <P>
     * @return true if an enum type has been set for this column or false otherwise
     */
    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);
    }
    
    @Override
    public Class<?> getJavaType()
    {
        Class<Enum<?>> enumType = getEnumType();
        if (enumType!=null)
            return enumType;
        // default
        return super.getJavaType();
    }

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