/*
 * 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.dolphinscheduler.api.service;

import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.User;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * users service
 */
public interface UsersService {

    /**
     * create user, only system admin have permission
     *
     * @param loginUser login user
     * @param userName user name
     * @param userPassword user password
     * @param email email
     * @param tenantId tenant id
     * @param phone phone
     * @param queue queue
     * @return create result code
     * @throws Exception exception
     */
    Map<String, Object> createUser(User loginUser, String userName, String userPassword, String email,
                                   int tenantId, String phone, String queue, int state) throws Exception;

    User createUser(String userName, String userPassword, String email,
                    int tenantId, String phone, String queue, int state);

    /***
     * create User for ldap login
     */
    User createUser(UserType userType, String userId, String email);

    /**
     * get user by user name
     *
     * @param userName user name
     * @return exist user or null
     */
    User getUserByUserName(String userName);

    /**
     * query user by id
     *
     * @param id id
     * @return user info
     */
    User queryUser(int id);

    /**
     * query user by ids
     *
     * @param ids id list
     * @return user list
     */
    List<User> queryUser(List<Integer> ids);

    /**
     * query user
     *
     * @param name name
     * @return user info
     */
    User queryUser(String name);

    /**
     * query user
     *
     * @param name name
     * @param password password
     * @return user info
     */
    User queryUser(String name, String password);

    /**
     * get user id by user name
     *
     * @param name user name
     * @return if name empty 0, user not exists -1, user exist user id
     */
    int getUserIdByName(String name);

    /**
     * query user list
     *
     * @param loginUser login user
     * @param pageNo page number
     * @param searchVal search avlue
     * @param pageSize page size
     * @return user list page
     */
    Result queryUserList(User loginUser, String searchVal, Integer pageNo, Integer pageSize);

    User updateUser(User loginUser,
                    Integer userId,
                    String userName,
                    String userPassword,
                    String email,
                    Integer tenantId,
                    String phone,
                    String queue,
                    int state,
                    String timeZone) throws IOException;

    /**
     * delete user
     *
     * @param loginUser login user
     * @param id user id
     * @return delete result code
     * @throws Exception exception when operate hdfs
     */
    Map<String, Object> deleteUserById(User loginUser, int id) throws IOException;

    /**
     * grant project
     *
     * @param loginUser login user
     * @param userId user id
     * @param projectIds project id array
     * @return grant result code
     */
    Map<String, Object> grantProject(User loginUser, int userId, String projectIds);

    /**
     * grant project with read permission
     *
     * @param loginUser login user
     * @param userId user id
     * @param projectIds project id array
     * @return grant result code
     */
    Map<String, Object> grantProjectWithReadPerm(User loginUser, int userId, String projectIds);

    /**
     * grant project by code
     *
     * @param loginUser login user
     * @param userId user id
     * @param projectCode project code
     * @return grant result code
     */
    Map<String, Object> grantProjectByCode(User loginUser, int userId, long projectCode);

    /**
     * revoke the project permission for specified user by id
     * @param loginUser     Login user
     * @param userId        User id
     * @param projectIds   project id array
     * @return
     */
    Map<String, Object> revokeProjectById(User loginUser, int userId, String projectIds);

    /**
     * revoke the project permission for specified user.
     * @param loginUser     Login user
     * @param userId        User id
     * @param projectCode   Project Code
     * @return
     */
    Map<String, Object> revokeProject(User loginUser, int userId, long projectCode);

    /**
     * grant udf function
     *
     * @param loginUser login user
     * @param userId user id
     * @param udfIds udf id array
     * @return grant result code
     */
    Map<String, Object> grantUDFFunction(User loginUser, int userId, String udfIds);

    /**
     * grant namespace
     *
     * @param loginUser login user
     * @param userId user id
     * @param namespaceIds namespace id array
     * @return grant result code
     */
    Map<String, Object> grantNamespaces(User loginUser, int userId, String namespaceIds);

    /**
     * grant datasource
     *
     * @param loginUser login user
     * @param userId user id
     * @param datasourceIds data source id array
     * @return grant result code
     */
    Map<String, Object> grantDataSource(User loginUser, int userId, String datasourceIds);

    /**
     * query user info
     *
     * @param loginUser login user
     * @return user info
     */
    Map<String, Object> getUserInfo(User loginUser);

    /**
     * query user list
     *
     * @param loginUser login user
     * @return user list
     */
    Map<String, Object> queryAllGeneralUsers(User loginUser);

    /**
     * query user list
     *
     * @param loginUser login user
     * @return user list
     */
    Map<String, Object> queryUserList(User loginUser);

    /**
     * verify user name exists
     *
     * @param userName user name
     * @return true if user name not exists, otherwise return false
     */
    Result<Object> verifyUserName(String userName);

    /**
     * unauthorized user
     *
     * @param loginUser login user
     * @param alertGroupId alert group id
     * @return unauthorize result code
     */
    Map<String, Object> unauthorizedUser(User loginUser, Integer alertGroupId);

    /**
     * authorized user
     *
     * @param loginUser login user
     * @param alertGroupId alert group id
     * @return authorized result code
     */
    Map<String, Object> authorizedUser(User loginUser, Integer alertGroupId);

    /**
     * registry user, default state is 0, default tenant_id is 1, no phone, no queue
     *
     * @param userName user name
     * @param userPassword user password
     * @param repeatPassword repeat password
     * @param email email
     * @return registry result code
     * @throws Exception exception
     */
    Map<String, Object> registerUser(String userName, String userPassword, String repeatPassword, String email);

    /**
     * activate user, only system admin have permission, change user state code 0 to 1
     *
     * @param loginUser login user
     * @param userName user name
     * @return create result code
     */
    Map<String, Object> activateUser(User loginUser, String userName);

    /**
     * activate user, only system admin have permission, change users state code 0 to 1
     *
     * @param loginUser login user
     * @param userNames user name
     * @return create result code
     */
    Map<String, Object> batchActivateUser(User loginUser, List<String> userNames);

    /**
     * Make sure user with given name exists, and create the user if not exists
     * <p>
     * ONLY for python gateway server, and should not use this in web ui function
     *
     * @param userName     user name
     * @param userPassword user password
     * @param email        user email
     * @param phone        user phone
     * @param tenantCode   tenant code
     * @param queue        queue
     * @param state        state
     * @return create result code
     */
    User createUserIfNotExists(String userName, String userPassword, String email, String phone, String tenantCode,
                               String queue,
                               int state) throws IOException;
}
