/*
 * 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.concurrent.atomic.AtomicInteger;

import org.apache.empire.commons.Options;
import org.apache.empire.data.Column;
import org.apache.empire.data.DataType;
import org.apache.empire.db.expr.column.DBValueExpr;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemExistsException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.xml.XMLUtil;
import org.w3c.dom.Element;


/**
 * This class represents a database view.
 * It contains methods to get and update records from the database
 */
public abstract class DBView extends DBRowSet
{
    // *Deprecated* private static final long serialVersionUID = 1L;

    /**
     * DBViewColumn
     * @author doebele
     */
    public static class DBViewColumn extends DBColumn
    {
        // *Deprecated* private static final long serialVersionUID = 1L;
      
        protected final DBColumnExpr expr;
        protected final DataType     dataType;
        protected final DBColumn     sourceColumn;
        protected final double       size;

        /**
         * Constructs a DBViewColumn object set the specified parameters to this object.
         * 
         * @param view the DBView object
         * @param expr the DBColumnExpr of the source table
         */
        protected DBViewColumn(DBView view, String name, DBColumnExpr expr, double size)
        { // call base
            super(view, name);
            // set Expression
            this.expr = expr;
            // set DataType
            DataType exprType = expr.getDataType();
            if (exprType==DataType.AUTOINC)
                exprType= DataType.INTEGER;
            this.dataType = exprType;
            // Source Column
            this.sourceColumn = expr.getSourceColumn();
            // from update column
            this.size = (sourceColumn!=null ? sourceColumn.getSize() : size);
            // Copy enumType
            Class<Enum<?>> enumType = expr.getEnumType();
            if (enumType!=null)
                setAttribute(Column.COLATTR_ENUMTYPE, enumType);
            // Add to view
            if (view != null)
                view.addColumn(this);
        }
        
        public DBColumnExpr getSourceColumnExpr()
        {
            return expr;
        }
        
        public DBView getView()
        {
            return (DBView)getRowSet();
        }

        @Override
        public DataType getDataType()
        {
            return dataType;
        }

        @Override
        public double getSize()
        {
            return size;
        }
        
        @Override
        public boolean isAutoGenerated()
        {
            if (sourceColumn==null)
                return false;
            return sourceColumn.isAutoGenerated();
        }

        @Override
        public boolean isReadOnly()
        {   
            if (getView().isUpdateable()==false)
                return true;
            // Check ReadOnly attribute 
            if (sourceColumn!=null)
                return sourceColumn.isReadOnly();
            // AUTOINC's are read only
            return isAutoGenerated();
        }

        @Override
        public boolean isRequired()
        {   
            if (getView().isUpdateable()==false)
                return false;
            // Check update Column
            if (sourceColumn==null)
                return false;
            return sourceColumn.isRequired();
        }    

        @Override
        public Object validateValue(Object value)
        {
            if (sourceColumn==null)
                return value;
            return sourceColumn.validateValue(value);
        }

        @Override
        public Object getAttribute(String name)
        {
            if (attributes != null && attributes.contains(name))
                return attributes.get(name);
            // Otherwise ask expression
            if (sourceColumn==null)
                return null;
            return sourceColumn.getAttribute(name);
        }

        @Override
        public Options getOptions()
        {
            if (options != null)
                return options;
            // Otherwise ask expression
            if (sourceColumn==null)
                return null;
            return sourceColumn.getOptions();
        }

        @Override
        public Element addXml(Element parent, long flags)
        {
            Element elem = XMLUtil.addElement(parent, "column");
            elem.setAttribute("name", name);
            // set default attributes
            if (sourceColumn != null)
                elem.setAttribute("source", sourceColumn.getFullName());
            // size
            double size = getSize();
            if (size > 0)
                elem.setAttribute("size", String.valueOf(size));
            // add All Attributes
            if (attributes != null)
                attributes.addXml(elem, flags);
            // add All Options
            Options fieldOptions = getOptions();
            if (fieldOptions != null)
                fieldOptions.addXml(elem, this.dataType);
            // done
            return elem;
        }

    }

    private static AtomicInteger viewCount = new AtomicInteger(0);

    private String               name;
    private String               alias;
    private DBViewColumn[]       keyColumns;
    private boolean              updateable;                      // true if the view is updateable
    private Boolean              quoteName = null;

    /**
     * Creates a view object for a given view in the database.
     * 
     * @param name the name of the view
     * @param db the database this view belongs to.
     * @param isUpdateable true if the records of this view can be updated 
     */
    public DBView(String name, DBDatabase db, boolean isUpdateable)
    { // Set the column expressions
        super(db);
        // Set Name and Alias
        this.name = name;
        this.alias = "v" + String.valueOf(viewCount.incrementAndGet());
        this.updateable = isUpdateable;
        // Add View to Database
        if (db != null && name != null)
            db.addView(this);
    }

    /**
     * Creates a view object for a given view in the database.
     * 
     * @param name the name of the view
     * @param db the database this view belongs to.
     */
    public DBView(String name, DBDatabase db)
    { // Set the column expressions
        this(name, db, false);
    }

    /**
     * Returns an array of all key columns.
     * @return an array of all key columns
     */
    @Override
    public DBColumn[] getKeyColumns()
    {
        return this.keyColumns;
    }
    
    /**
     * identifies the columns that uniquely identify a row in the view
     * @param keyColumns list of columns that uniquely identify a row 
     */
    protected void setKeyColumns(DBViewColumn... keyColumns)
    { // Set Key Columns
        this.keyColumns = keyColumns;
    }

    /**
     * identifies the column that uniquely identifies a row in the view
     * @param keyColumn the column that uniquely identifies a row 
     */
    protected void setKeyColumn(DBViewColumn keyColumn)
    {
        if (keyColumn != null)
            setKeyColumns(new DBViewColumn[] { keyColumn });
        else
            setKeyColumns((DBViewColumn[]) null);
    }
    
    /**
     * Use this to create a new View command inside the createCommand() method!
     * @return a new command for this view
     */
    protected DBCommand newCommand()
    {
        return db.getDbms().createCommand(false);
    }

    /**
     * Returns the command required to create the view<br>
     * This is function is only used for the creation of DDL statements
     * @return a command expression that is used to create the view
     */
    public abstract DBCommandExpr createCommand();

    /**
     * Returns the view name of this object.
     * @return the view name of this object
     */
    @Override
    public String getName()
    {
        return name;
    }

    /**
     * Returns the full qualified table name.
     * @return the full qualified table name
     */
    @Override
    public String getFullName()
    {
        String schema = db.getSchema();
        return (schema != null) ? schema + "." + name : name;
    }

    /**
     * Returns the alias name of this object.
     * @return the alias name of this object
     */
    @Override
    public String getAlias()
    {
        return alias;
    }
    
    /**
     * Returns whether or not the view is updateable
     * @return true if the view is updateable or false if not 
     */
    @Override
    public boolean isUpdateable()
    {
        return this.updateable;
    }

    /**
     * Adds a column to the view.
     * 
     * @param col a view column object
     */
    protected void addColumn(DBViewColumn col)
    { // find column by name
        if (col == null || col.getRowSet() != this)
            throw new InvalidArgumentException("col", col);
        if (getColumn(col.getName())!=null)
            throw new ItemExistsException(col.getName());
        // add now
        columns.add(col);
    }

    /**
     * Adds a column to the view.
     * 
     * @param columnName name of the column in the view
     * @param dataType the data type of the column
     * @param size the size of the column
     * @return true if the column was successfully added or false otherwise
     */
    protected final DBViewColumn addColumn(String columnName, DataType dataType, double size)
    {   // find column by name
        return new DBViewColumn(this, columnName, new DBValueExpr(db, null, dataType), size);
    }

    /**
     * Adds a column to the view.
     * 
     * @param columnName name of the column in the view
     * @param dataType the data type of the column
     * @return true if the column was successfully added or false otherwise
     */
    protected final DBViewColumn addColumn(String columnName, DataType dataType)
    {   // find column by name
        return new DBViewColumn(this, columnName, new DBValueExpr(db, null, dataType), 0.0d);
    }

    /**
     * Adds a column to the view.
     * 
     * @param columnName name of the column in the view
     * @param columnExpr the column expression that builds the column
     * @return true if the column was successfully added or false otherwise
     */
    protected final DBViewColumn addColumn(String columnName, DBColumnExpr columnExpr)
    {   // find column by name
        return new DBViewColumn(this, columnName, columnExpr, 0.0d);
    }

    /**
     * Adds a column to the view based on an existing column in another table or view.
     * 
     * @param sourceColumn existing column in another table or view  
     * @return the view column object
     */
    protected final DBViewColumn addColumn(DBTableColumn sourceColumn)
    {   // find column by name
        return new DBViewColumn(this, sourceColumn.getName(), sourceColumn, 0.0d);
    }

    /**
     * This function searchs for equal columns given by the specified DBColumnExpr object.
     * 
     * @param expr the DBColumnExpr object
     * @return the located column (only DBViewColumn objects)
     */
    public DBViewColumn findViewColumn(DBColumnExpr expr)
    {
        for (int i = 0; i < columns.size(); i++)
        {
            DBViewColumn vc = (DBViewColumn) columns.get(i);
            if (vc.expr.equals(expr))
                return vc;
        }
        // not found
        return null;
    }

    /**
     * Creates the SQL-Command adds the alias name to the SQL-Command.
     * 
     * @param buf the SQL-Command
     * @param context the current SQL-Command context
     */
    @Override
    public void addSQL(StringBuilder buf, long context)
    {
        // Append Name
        if ((context & CTX_NAME|CTX_FULLNAME)!=0)
        {   // append Qualified Name 
            db.appendQualifiedName(buf, name, quoteName);
        }
        // Append Alias
        if ((context & CTX_ALIAS)!=0 && alias!=null)
        {    // append alias
             buf.append(getRenameTablePhrase());
             buf.append(alias);
        }
    }

    @Override
    public void updateRecord(DBRecordBase rec)
    {
        if (updateable==false)
            throw new NotSupportedException(this, "updateRecord");
        // Update the record
        super.updateRecord(rec);
    }
    
    /*
     * (non-Javadoc)
     * 
     * @see org.apache.empire.db.DBRowSet#addRecord(org.apache.empire.db.DBRecord, java.sql.Connection)
     */
    @Override
    public void createRecord(DBRecordBase record, Object[] initalKey, boolean deferredInit)
    {
        throw new NotSupportedException(this, "createRecord");
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.empire.db.DBRowSet#deleteRecord(java.lang.Object[], java.sql.Connection, boolean)
     */
    @Override
    public void deleteRecord(Object[] key, DBContext context)
    {
        throw new NotSupportedException(this, "deleteRecord");
    }
}