/*
 *   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.directory.fortress.web.model;

import org.apache.commons.lang.StringUtils;
import org.apache.directory.fortress.core.util.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.wicket.injection.Injector;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.directory.fortress.core.AuditMgr;
import org.apache.directory.fortress.core.ReviewMgr;
import org.apache.directory.fortress.core.model.Mod;
import org.apache.directory.fortress.core.model.Session;
import org.apache.directory.fortress.core.model.User;
import org.apache.directory.fortress.core.model.UserAudit;
import org.apache.directory.fortress.core.SecurityException;

import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class AuditModListModel extends Model<SerializableList<Mod>>
{
    /** Default serialVersionUID */
    private static final long serialVersionUID = 1L;

    @SpringBean
    private AuditMgr auditMgr;
    @SpringBean
    private ReviewMgr reviewMgr;
    private static final Logger LOG = LoggerFactory.getLogger(AuditModListModel.class.getName());
    private UserAudit userAudit;
    private SerializableList<Mod> mods = null;

    /**
     * Default constructor
     */
    public AuditModListModel( final Session session )
    {
        Injector.get().inject(this);
        if (Config.getInstance().getBoolean(org.apache.directory.fortress.core.GlobalIds.IS_ARBAC02))
        {
            auditMgr.setAdmin(session);
        }
    }
    

    /**
     * User contains the search arguments.
     *
     * @param userAudit
     */
    public AuditModListModel( UserAudit userAudit, Session session )
    {
        Injector.get().inject(this);
        this.userAudit = userAudit;
        if (Config.getInstance().getBoolean(org.apache.directory.fortress.core.GlobalIds.IS_ARBAC02))
        {
            auditMgr.setAdmin(session);
        }
    }

    /**
     * This data is bound for RoleListPanel
     *
     * @return T extends List<Role> roles data will be bound to panel data view component.
     */
    @Override
    public SerializableList<Mod> getObject()
    {
        if (mods != null)
        {
            LOG.debug( ".getObject count: " + mods.size() );
            return mods;
        }
        
        // if caller did not set userId return an empty list:
        if ( ( userAudit == null ) ||
             ( 
                 !StringUtils.isNotEmpty( userAudit.getUserId() )  &&
                 !StringUtils.isNotEmpty( userAudit.getObjName() )  &&
                 !StringUtils.isNotEmpty( userAudit.getOpName() )  &&
                 ( userAudit.getBeginDate() == null ) &&
                 ( userAudit.getEndDate() == null )
             )
           )
        {
            LOG.debug( ".getObject null" );
            mods = new SerializableList<>( new ArrayList<Mod>() );
        }
        else
        {
            // do we need to retrieve the internalUserId (which is what maps to admin modification record in slapd audit log?
            if ( StringUtils.isNotEmpty( userAudit.getUserId() ) && !StringUtils.isNotEmpty( userAudit
                .getInternalUserId() ) )
            {
                User user = getUser( userAudit );
                if ( user == null )
                {
                    String warning = "Matching user not found for userId: " + userAudit.getUserId();
                    LOG.warn( warning );
                    //throw new RuntimeException( warning );
                }
                else
                {
                    userAudit.setInternalUserId( user.getInternalId() );
                }
            }
            mods = new SerializableList<>( getList( userAudit ) );
        }
        
        return mods;
    }
    

    @Override
    public void setObject( SerializableList<Mod> object )
    {
        LOG.debug(".setObject count: " + object.size() );
        this.mods = object;
    }

    
    @Override
    public void detach()
    {
        this.mods = null;
        userAudit = null;
    }

    
    private List<Mod> getList( UserAudit userAudit )
    {
        List<Mod> modList = null;
        
        try
        {
            userAudit.setDn( "" );
            
            if ( StringUtils.isNotEmpty( userAudit.getObjName() ) )
            {
                userAudit.setObjName( getTruncatedObjName( userAudit.getObjName() ) );
            }
            
            modList = auditMgr.searchAdminMods( userAudit );
        }
        catch ( org.apache.directory.fortress.core.SecurityException se )
        {
            String error = ".getList caught SecurityException=" + se;
            LOG.warn(error);
            // create empty model object to prevent npe in listview.
            modList = new SerializableList<>( new ArrayList<Mod>() );
        }
        
        return modList;
    }
    

    /**
     * Utility will parse a String containing objName.operationName and return the objName only.
     *
     * @param szObj contains raw data format.
     * @return String containing objName.
     */
    private String getTruncatedObjName( String szObj )
    {
        int indx = szObj.lastIndexOf( '.' );
        
        if ( indx == -1 )
        {
            return szObj;
        }
        
        return szObj.substring( indx + 1 );
    }
    

    private User getUser( UserAudit userAudit )
    {
        User user = null;
        
        try
        {
            user = reviewMgr.readUser( new User ( userAudit.getUserId() ) );
        }
        catch ( SecurityException se )
        {
            String error = ".getUser caught SecurityException=" + se;
            LOG.warn( error );
        }
        
        return user;
    }
}
