package org.apache.archiva.redback.rest.services.v2;
/*
 * 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 org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.integration.util.RoleSorter;
import org.apache.archiva.redback.rbac.Permission;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
import org.apache.archiva.redback.rbac.Resource;
import org.apache.archiva.redback.rest.api.MessageKeys;
import org.apache.archiva.redback.rest.api.model.ErrorMessage;
import org.apache.archiva.redback.rest.api.model.Role;
import org.apache.archiva.redback.rest.api.model.RoleTemplate;
import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
import org.apache.archiva.redback.rest.api.services.v2.RoleService;
import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
import org.apache.archiva.redback.role.RoleExistsException;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.role.RoleManagerException;
import org.apache.archiva.redback.role.RoleNotFoundException;
import org.apache.archiva.redback.role.model.ModelTemplate;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserManagerException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author Olivier Lamy
 * @since 1.3
 */
@Service("v2.roleService#rest")
public class DefaultRoleService extends BaseRedbackService
    implements RoleService
{

    private Logger log = LoggerFactory.getLogger( DefaultRoleService.class );

    private RoleManager roleManager;

    @Context
    private HttpServletRequest httpServletRequest;

    @Context
    private HttpServletResponse httpServletResponse;

    @Context
    private UriInfo uriInfo;

    private static final String[] DEFAULT_SEARCH_FIELDS = {"name", "description"};
    private static final Map<String, BiPredicate<String, org.apache.archiva.redback.rbac.Role>> FILTER_MAP = new HashMap<>( );
    private static final Map<String, Comparator<org.apache.archiva.redback.rbac.Role>> ORDER_MAP = new HashMap<>( );
    private static final QueryHelper<org.apache.archiva.redback.rbac.Role> QUERY_HELPER;

    static
    {

        QUERY_HELPER = new QueryHelper<>( FILTER_MAP, ORDER_MAP, DEFAULT_SEARCH_FIELDS );
        QUERY_HELPER.addStringFilter( "name", org.apache.archiva.redback.rbac.Role::getName );
        QUERY_HELPER.addStringFilter( "description", org.apache.archiva.redback.rbac.Role::getDescription );
        QUERY_HELPER.addBooleanFilter( "assignable", org.apache.archiva.redback.rbac.Role::isAssignable );

        // The simple Comparator.comparing(attribute) is not null safe
        // As there are attributes that may have a null value, we have to use a comparator with nullsLast(naturalOrder)
        // and the wrapping Comparator.nullsLast(Comparator.comparing(attribute)) does not work, because the attribute is not checked by the nullsLast-Comparator
        QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.redback.rbac.Role::getName );
        QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.redback.rbac.Role::getId );
        QUERY_HELPER.addNullsafeFieldComparator( "resource", org.apache.archiva.redback.rbac.Role::getResource );
        QUERY_HELPER.addNullsafeFieldComparator( "assignable", org.apache.archiva.redback.rbac.Role::isAssignable );
        QUERY_HELPER.addNullsafeFieldComparator( "template_instance", org.apache.archiva.redback.rbac.Role::isTemplateInstance );
    }

    @Inject
    public DefaultRoleService( RoleManager roleManager,
                               @Named(value = "rbacManager#default") RBACManager rbacManager,
                               @Named(value = "userManager#default") UserManager userManager )
    {
        super( rbacManager, userManager );
        this.roleManager = roleManager;

        log.debug( "use rbacManager impl: {}", rbacManager.getClass().getName() );
        log.debug( "use userManager impl: {}", userManager.getClass().getName() );
    }

    @Override
    public PagedResult<RoleInfo> getAllRoles( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws RedbackServiceException
    {
        boolean ascending = !"desc".equals( order );
        try
        {
            // UserQuery does not work here, because the configurable user manager does only return the query for
            // the first user manager in the list. So we have to fetch the whole role list
            List<? extends org.apache.archiva.redback.rbac.Role> rawRoles = rbacManager.getAllRoles( );
            Predicate<org.apache.archiva.redback.rbac.Role> filter = QUERY_HELPER.getQueryFilter( searchTerm );
            long size = rawRoles.stream( ).filter( filter ).count( );
            List<RoleInfo> users = rawRoles.stream( )
                .filter( filter )
                .sorted( QUERY_HELPER.getComparator( orderBy, ascending ) ).skip( offset ).limit( limit )
                .map( role -> {
                    try
                    {
                        return Optional.of( getRoleInfo( role ) );
                    }
                    catch ( RedbackServiceException e )
                    {
                        return Optional.<RoleInfo>empty();
                    }
                } ).filter(Optional::isPresent)
                .map(Optional::get)
                .collect( Collectors.toList( ) );
            return new PagedResult<>( (int) size, offset, limit, users );
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL , e.getMessage( )) );
        }

    }

    @Override
    public RoleInfo getRole( String roleId ) throws RedbackServiceException
    {
        try
        {
            org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRoleById( roleId );
            RoleInfo role = getRoleInfo( rbacRole );
            return role;
        }
        catch ( RbacObjectNotFoundException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, roleId ), 404 );
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
    }

    @Override
    public Response checkRole( String roleId ) throws RedbackServiceException
    {
        try
        {
            org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRoleById( roleId );
            if (rbacRole==null) {
                return Response.status( 404 ).build();
            } else
            {
                return Response.ok( ).build( );
            }
        }
        catch ( RbacObjectNotFoundException e )
        {
            return Response.status( 404 ).build();
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
    }



    @Override
    public RoleInfo moveTemplatedRole( String templateId, String oldResource, String newResource )
        throws RedbackServiceException
    {
        try
        {
            if (StringUtils.isEmpty( templateId ) || StringUtils.isEmpty( oldResource ) || StringUtils.isEmpty( newResource )) {
                throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
            }
            boolean sourceExists = roleManager.templatedRoleExists( templateId, oldResource );
            if (!sourceExists) {
                throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_NOT_FOUND, templateId, oldResource ), 404 );
            }
            boolean destExists = roleManager.templatedRoleExists( templateId, newResource );
            if (destExists) {
                httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build(  ).normalize().toString() );
                throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, newResource ), 303 );
            }
            String roleId = roleManager.moveTemplatedRole( templateId, oldResource, newResource );
            httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build(  ).normalize().toString() );
            httpServletResponse.setStatus( 201 );
            return getRoleInfo( rbacManager.getRoleById( roleId ) );
        }
        catch ( RoleExistsException e ) {
            httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build(  ).normalize().toString() );
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, newResource ), 303 );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
    }


    @Override
    public Response checkTemplateRole( String templateId, String resource )
        throws RedbackServiceException
    {
        try
        {
            if (roleManager.templatedRoleExists( templateId, resource )) {
                return Response.ok( ).build( );
            } else {
                return Response.status( 404 ).build();
            }
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( e.getMessage() );
        }

    }

    @Override
    public RoleInfo createTemplatedRole( String templateId, String resource )
        throws RedbackServiceException
    {
        if (StringUtils.isEmpty( templateId )) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
        }
        if (StringUtils.isEmpty( resource )) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
        }
        try
        {
            boolean exists = roleManager.templatedRoleExists( templateId, resource );
            String roleId = roleManager.createTemplatedRole( templateId, resource );
            httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(roleId).build(  ).normalize().toString() );
            if (exists)
            {
                httpServletResponse.setStatus( 200 );
            } else {
                httpServletResponse.setStatus( 201 );
            }
            return getRoleInfo( rbacManager.getRoleById( roleId ) );
        } catch (RoleNotFoundException e) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, templateId, resource ), 404 );
        } catch (RoleExistsException e) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, resource ), 303 );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
    }

    @Override
    public Response removeTemplatedRole( String templateId, String resource )
        throws RedbackServiceException
    {

        try
        {
            roleManager.removeTemplatedRole( templateId, resource );
            return Response.ok( ).build( );
        }
        catch ( RoleNotFoundException e ) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_NOT_FOUND, templateId, resource ), 404 );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
        }
    }



    @Override
    public RoleInfo assignRole( String roleId, String userId )
        throws RedbackServiceException
    {
        try
        {
            userManager.findUser( userId );
            roleManager.assignRole( roleId, userId );
            return getRoleInfo( rbacManager.getRoleById( roleId ) );
        }
        catch ( RoleNotFoundException e ) {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, e.getMessage( ) ), 404 );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
        }
        catch ( UserNotFoundException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USER_NOT_FOUND, e.getMessage( ) ), 404 );
        }
        catch ( UserManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
        }
        catch ( RbacObjectNotFoundException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
        catch ( RbacManagerException e )
        {
            throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
        }
    }


    @Override
    public RoleInfo assignTemplatedRole( String templateId, String resource, String principal )
        throws RedbackServiceException
    {
        try
        {
            roleManager.assignTemplatedRole( templateId, resource, principal );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( e.getMessage() );
        }
        return null;
    }

    @Override
    public RoleInfo unassignRole( String roleId, String principal )
        throws RedbackServiceException
    {
        try
        {
            roleManager.unassignRole( roleId, principal );
        }
        catch ( RoleManagerException e )
        {
            throw new RedbackServiceException( e.getMessage() );
        }
        return null;
    }

    @Override
    public RoleInfo updateRole( String roleId, Role role ) throws RedbackServiceException
    {
        return null;
    }



//    public List<Role> getEffectivelyAssignedRoles( String username )
//        throws RedbackServiceException
//    {
//        if ( StringUtils.isEmpty( username ) )
//        {
//            throw new RedbackServiceException( new ErrorMessage( "user.cannot.be.null" ) );
//        }
//        try
//        {
//            List<? extends org.apache.archiva.redback.rbac.Role> roles =
//                filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( username ) );
//
//            List<Role> effectivelyAssignedRoles = new ArrayList<Role>( roles.size() );
//
//            for ( org.apache.archiva.redback.rbac.Role r : roles )
//            {
//                effectivelyAssignedRoles.add( new Role( r ) );
//            }
//
//            Collections.sort( effectivelyAssignedRoles, RoleComparator.INSTANCE  );
//
//            return effectivelyAssignedRoles;
//        }
//        catch ( RbacManagerException rme )
//        {
//            // ignore, this can happen when the user has no roles assigned
//        }
//        return new ArrayList<Role>( 0 );
//    }


    //----------------------------------------------------------------
    // Internal methods
    //----------------------------------------------------------------


}
