package org.apache.archiva.redback.management;

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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;

import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.keys.KeyManager;
import org.apache.archiva.redback.keys.jdo.AuthenticationKeyDatabase;
import org.apache.archiva.redback.keys.jdo.io.stax.RedbackKeyManagementJdoStaxReader;
import org.apache.archiva.redback.keys.jdo.io.stax.RedbackKeyManagementJdoStaxWriter;
import org.apache.archiva.redback.rbac.Operation;
import org.apache.archiva.redback.rbac.Permission;
import org.apache.archiva.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.rbac.Role;
import org.apache.archiva.redback.rbac.jdo.RbacDatabase;
import org.apache.archiva.redback.rbac.jdo.io.stax.RbacJdoModelStaxReader;
import org.apache.archiva.redback.rbac.jdo.io.stax.RbacJdoModelStaxWriter;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.rbac.Resource;
import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.jdo.UserDatabase;
import org.apache.archiva.redback.users.jdo.io.stax.UsersManagementStaxReader;
import org.apache.archiva.redback.users.jdo.io.stax.UsersManagementStaxWriter;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;

/**
 * JDO implementation of the data management tool.
 *
 * TODO do we really need JDO specifics here? Could optimize by going straight to JDOFactory
 * TODO check whether this current method logs everything unnecessarily.
 */
@Service("dataManagementTool#jdo")
public class JdoDataManagementTool
    implements DataManagementTool
{
    private static final String USERS_XML_NAME = "users.xml";

    private static final String KEYS_XML_NAME = "keys.xml";

    private static final String RBAC_XML_NAME = "rbac.xml";

    public void backupRBACDatabase( RBACManager manager, File backupDirectory )
        throws RbacManagerException, IOException, XMLStreamException
    {
        RbacDatabase database = new RbacDatabase();
        database.setRoles( manager.getAllRoles() );
        database.setUserAssignments( manager.getAllUserAssignments() );
        database.setPermissions( manager.getAllPermissions() );
        database.setOperations( manager.getAllOperations() );
        database.setResources( manager.getAllResources() );

        RbacJdoModelStaxWriter writer = new RbacJdoModelStaxWriter();
        Writer fileWriter = createWriter( backupDirectory, RBAC_XML_NAME, database.getModelEncoding() );
        try
        {
            writer.write( fileWriter, database );
        }
        finally
        {
            IOUtils.closeQuietly( fileWriter );
        }
    }

    public void backupUserDatabase( UserManager manager, File backupDirectory )
        throws IOException, XMLStreamException, UserManagerException
    {
        UserDatabase database = new UserDatabase();
        database.setUsers( manager.getUsers() );

        UsersManagementStaxWriter writer = new UsersManagementStaxWriter();
        Writer fileWriter = createWriter( backupDirectory, USERS_XML_NAME, database.getModelEncoding() );
        try
        {
            writer.write( fileWriter, database );
        }
        finally
        {
            IOUtils.closeQuietly( fileWriter );
        }
    }

    public void backupKeyDatabase( KeyManager manager, File backupDirectory )
        throws IOException, XMLStreamException
    {
        try
        {
            manager.removeExpiredKeys();
        }
        catch ( KeyManagerException e )
        {
            throw new IOException( "Error removing expired keys" );
        }

        AuthenticationKeyDatabase database = new AuthenticationKeyDatabase();
        database.setKeys( manager.getAllKeys() );

        RedbackKeyManagementJdoStaxWriter writer = new RedbackKeyManagementJdoStaxWriter();
        Writer fileWriter = createWriter( backupDirectory, KEYS_XML_NAME, database.getModelEncoding() );
        try
        {
            writer.write( fileWriter, database );
        }
        finally
        {
            IOUtils.closeQuietly( fileWriter );
        }
    }

    @SuppressWarnings("unchecked")
    public void restoreRBACDatabase( RBACManager manager, File backupDirectory )
        throws IOException, XMLStreamException, RbacManagerException
    {
        RbacJdoModelStaxReader reader = new RbacJdoModelStaxReader();

        FileReader fileReader = new FileReader( new File( backupDirectory, RBAC_XML_NAME ) );

        RbacDatabase database;
        try
        {
            database = reader.read( fileReader );
        }
        finally
        {
            IOUtils.closeQuietly( fileReader );
        }

        Map<String, Permission> permissionMap = new HashMap<String, Permission>();
        Map<String, Resource> resources = new HashMap<String, Resource>();
        Map<String, Operation> operations = new HashMap<String, Operation>();
        for ( Role role : (List<Role>) database.getRoles() )
        {
            // TODO: this could be generally useful and put into saveRole itself as long as the performance penalty isn't too harsh.
            //   Currently it always saves everything where it could pull pack the existing permissions, etc if they exist
            List<Permission> permissions = new ArrayList<Permission>();
            for ( Permission permission : role.getPermissions() )
            {
                if ( permissionMap.containsKey( permission.getName() ) )
                {
                    permission = permissionMap.get( permission.getName() );
                }
                else if ( manager.permissionExists( permission ) )
                {
                    permission = manager.getPermission( permission.getName() );
                    permissionMap.put( permission.getName(), permission );
                }
                else
                {
                    Operation operation = permission.getOperation();
                    if ( operations.containsKey( operation.getName() ) )
                    {
                        operation = operations.get( operation.getName() );
                    }
                    else if ( manager.operationExists( operation ) )
                    {
                        operation = manager.getOperation( operation.getName() );
                        operations.put( operation.getName(), operation );
                    }
                    else
                    {
                        operation = manager.saveOperation( operation );
                        operations.put( operation.getName(), operation );
                    }
                    permission.setOperation( operation );

                    Resource resource = permission.getResource();
                    if ( resources.containsKey( resource.getIdentifier() ) )
                    {
                        resource = resources.get( resource.getIdentifier() );
                    }
                    else if ( manager.resourceExists( resource ) )
                    {
                        resource = manager.getResource( resource.getIdentifier() );
                        resources.put( resource.getIdentifier(), resource );
                    }
                    else
                    {
                        resource = manager.saveResource( resource );
                        resources.put( resource.getIdentifier(), resource );
                    }
                    permission.setResource( resource );

                    permission = manager.savePermission( permission );
                    permissionMap.put( permission.getName(), permission );
                }
                permissions.add( permission );
            }
            role.setPermissions( permissions );

            manager.saveRole( role );
        }

        for ( UserAssignment userAssignment : (List<UserAssignment>) database.getUserAssignments() )
        {
            manager.saveUserAssignment( userAssignment );
        }
    }

    @SuppressWarnings("unchecked")
    public void restoreUsersDatabase( UserManager manager, File backupDirectory )
        throws IOException, XMLStreamException, UserManagerException
    {
        UsersManagementStaxReader reader = new UsersManagementStaxReader();

        FileReader fileReader = new FileReader( new File( backupDirectory, USERS_XML_NAME ) );

        UserDatabase database;
        try
        {
            database = reader.read( fileReader );
        }
        finally
        {
            IOUtils.closeQuietly( fileReader );
        }

        for ( User user : (List<User>) database.getUsers() )
        {
            manager.addUserUnchecked( user );
        }
    }

    @SuppressWarnings("unchecked")
    public void restoreKeysDatabase( KeyManager manager, File backupDirectory )
        throws IOException, XMLStreamException
    {
        RedbackKeyManagementJdoStaxReader reader = new RedbackKeyManagementJdoStaxReader();

        FileReader fileReader = new FileReader( new File( backupDirectory, KEYS_XML_NAME ) );

        AuthenticationKeyDatabase database;
        try
        {
            database = reader.read( fileReader );
        }
        finally
        {
            IOUtils.closeQuietly( fileReader );
        }

        for ( AuthenticationKey key : (List<AuthenticationKey>) database.getKeys() )
        {
            manager.addKey( key );
        }
    }

    public void eraseRBACDatabase( RBACManager manager )
    {
        manager.eraseDatabase();
    }

    public void eraseUsersDatabase( UserManager manager )
    {
        manager.eraseDatabase();
    }

    public void eraseKeysDatabase( KeyManager manager )
    {
        manager.eraseDatabase();
    }

    private Writer createWriter( File directory, String file, String encoding )
        throws FileNotFoundException
    {
        File f = new File( directory, file );
        File parentFile = f.getParentFile();
        parentFile.mkdirs();

        FileOutputStream out = new FileOutputStream( f );
        return new OutputStreamWriter( out, Charset.forName( encoding ) );
    }
}
