/*
 * 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.jsf2.pageelements;

import java.sql.Connection;

import javax.faces.context.FacesContext;

import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBRowSet;
import org.apache.empire.exceptions.EmpireException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ObjectNotValidException;
import org.apache.empire.jsf2.app.FacesUtils;
import org.apache.empire.jsf2.pages.Page;
import org.apache.empire.jsf2.pages.PageDefinition;
import org.apache.empire.jsf2.pages.PageElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RecordPageElement<T extends DBRecord> extends PageElement
{
    private static final long   serialVersionUID = 1L;

    private static final Logger log              = LoggerFactory.getLogger(RecordPageElement.class);

    protected DBRowSet rowset;

    protected T record;
    
    /**
     * Creates a record page element for the given Table or View
     * @param page the page element
     * @param rowset Table or View
     * @param record the record object for this page element
     * @param propertyName the property name which is used to get and retrieve session information
     */
    public RecordPageElement(Page page, DBRowSet rowset, T record, String propertyName)
    {
        super(page, propertyName);
        // Set Rowset and Record
        this.rowset = rowset;
        this.record = record;
        // log
        log.debug("RecordPageSupport for {} created.", rowset.getName());
    }

    /**
     * Creates a record page element for the given Table or View
     * @param page the page element
     * @param rowset Table or View
     * @param record the record object for this page element
     */
    public RecordPageElement(Page page, DBRowSet rowset, T record)
    {
        this(page, rowset, record, getDefaultPropertyName(rowset));
    }
    
    public T getRecord()
    {
        return record;
    }
    
    public DBRowSet getRowSet()
    {
        return record.getRowSet();
    }
    
    public String getRecordIdParam()
    {
        if (!record.isValid())
            return null;
        // idParam
        Object[] key = record.getKeyValues();
        return getPage().getIdParamForKey(rowset, key);
    }

    @Override
    protected void onInitPage()
    {
        // Chance to init the page
        if (record.isValid()==false)
            reloadRecord();
    }

    /**
     * return true if the record can be restored from the session.
     * @param newRecord flag to detect session data for a new reaord otherwise for an existing record
     * @return true if information to restore the record is available on the session
     */
    public boolean canReloadRecord(boolean newRecord)
    {
        if (newRecord)
            return (getSessionObject(DBRecord.class)!=null);
        else
            return (getSessionObject(Object[].class)!=null); 
    }
    
    /**
     * loads the record identified by the supplied key from the database<BR>
     */
    public void reloadRecord()
    {
        Object[] recKey = getSessionObject(Object[].class);
        // Check Key
        if (recKey==null || recKey.length==0)
        {   // Invalid Record key
            T rec = (T)getSessionObject(DBRecord.class);
            if (rec!=null)
            {   // A new record
                record = rec;
                return;
            }    
            // Not Valid
            throw new ObjectNotValidException(record);
        }
        // Record laden
        Connection conn = getPage().getConnection(rowset.getDatabase()); 
        record.read(rowset, recKey, conn);
    }
    
    /**
     * loads the record identified by the supplied key from the database<BR>
     */
    public void loadRecord(Object[] recKey)
    {
        // Check Key
        if (recKey==null || recKey.length==0)
        {   // Invalid Record key
            throw new InvalidArgumentException("recKey", recKey);
        }
        // Put key on Session
        this.removeSessionObject(DBRecord.class);
        this.setSessionObject(Object[].class, recKey);
        // Record laden
        Connection conn = getPage().getConnection(rowset.getDatabase()); 
        record.read(rowset, recKey, conn);
    }

    /**
     * loads an existing record
     * @param idParam
     */
    public void loadRecord(String idParam)
    {
        Object[] key = getPage().getKeyFromParam(rowset, idParam);
        loadRecord(key);
    }
    
    /**
     * loads an existing record the the specified page
     * 
     * @param page
     * @param idParam
     */
    public void loadRecord(PageDefinition page, String idParam) {
        Object[] key = getPage().getKeyFromParam(page, rowset, idParam);
        loadRecord(key);
    }
    
    /**
     * creates a new record
     */
    public void createRecord()
    {
        Connection conn = getPage().getConnection(rowset.getDatabase()); 
        record.create(rowset, conn);
        // Put key on Session
        this.removeSessionObject(Object[].class);
        this.setSessionObject(DBRecord.class, record);
    }

    /**
     * updates or inserts the record in the database
     */
    public boolean updateRecord()
    {
        // Record laden
        try {
            // Check Key
            if (record.isValid()==false)
            {   // Invalid Record key
                throw new ObjectNotValidException(record); 
            }
            // Check Modified
            if (record.isModified()==false)
            {   // Not Modified
                return true; 
            }
            Connection conn = getPage().getConnection(rowset.getDatabase()); 
            record.update(conn);
            // Put key on Session
            this.removeSessionObject(DBRecord.class);
            this.setSessionObject(Object[].class, record.getKeyValues());
            return true; 
            // OK
        } catch(Exception e) {
            // Wrap exception
            if (!(e instanceof EmpireException))
                e = new InternalException(e);
            // Set error Message
            FacesContext fc = FacesUtils.getContext();
            String msg = FacesUtils.getTextResolver(fc).getExceptionMessage(e);
            FacesUtils.addErrorMessage(fc, msg);
            return false; 
        }
    }
    
    /**
     * deletes a record
     */
    public void deleteRecord()
    {
        // check valid
        if (!record.isValid())
            throw new ObjectNotValidException(record);
        // delete
        Connection conn = getPage().getConnection(rowset.getDatabase()); 
        record.delete(conn);
        // Put key on Session
        this.removeSessionObject(Object[].class);
        this.removeSessionObject(DBRecord.class);
    }
    
    /**
     * closes a record
     */
    public void closeRecord()
    {
        record.close();
        // Put key on Session
        this.removeSessionObject(Object[].class);
        this.removeSessionObject(DBRecord.class);
    }

}
