package com.foreverwin.mesnac.dataimport.util;


import com.alibaba.fastjson.JSONObject;
import com.foreverwin.mesnac.dataimport.exception.AuthenticationException;
import com.sap.me.frame.domain.BusinessException;
import com.sap.security.api.*;
import com.sap.security.api.logon.ILoginConstants;
import com.sap.tc.logging.Category;
import com.sap.tc.logging.Location;
import com.sap.tc.logging.Severity;
import com.sap.tc.logging.SimpleLogger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Authenticate {

    /**
     * {@inheritDoc}
     */
    public static void authenticate(String userId, String password) throws BusinessException {
        IUserAccountFactory uaFactory = UMFactory.getUserAccountFactory();

        IUserAccount ua = null;
        try {
            ua = uaFactory.getUserAccountByLogonId(userId);
        } catch (UMException e) {
            throw new AuthenticationException();
        }
        if (ua == null) {
            throw new AuthenticationException();
        }

        int checkStatus = 0;
        try {
            checkStatus = ua.checkPasswordExtended(password);
        } catch (UMException e) {
            throw new AuthenticationException();
        }

        switch (checkStatus) {
            case ILoginConstants.CHECKPWD_OK:
                return;
            default:
                throw new AuthenticationException();
        }
    }

    //JSONObject data
    public static void createMEUser(String userId, String password) throws BusinessException {
        JSONObject data = new JSONObject();

        data.put("id" , userId);
        data.put("password" , password);
        createMEUser(data);

    }

    public static void createMEUser(JSONObject data) throws BusinessException {

        IUserFactory userFactory = UMFactory.getUserFactory();

        if (!AppUtil.isNotNull(data.getString("id"))) {
            return;
        }

        if (!AppUtil.isNotNull(data.getString("password"))) {
            return;
        }

        String password = data.getString("password");
        String userId = data.getString("id");

        try {
            IUserMaint user = userFactory.newUser(userId);

            if (data.containsKey("lastname")) {
                if (AppUtil.isNotNull(data.getString("lastname"))) {
                    user.setLastName(data.getString("lastname"));
                }
            }

            if (data.containsKey("firstname")) {
                if (AppUtil.isNotNull(data.getString("firstname"))) {
                    user.setFirstName(data.getString("firstname"));
                }
            }
            if (data.containsKey("email")) {
                if (AppUtil.isNotNull(data.getString("email"))) {
                    user.setEmail(data.getString("email"));
                }
            }

            if (data.containsKey("cellphone")) {
                if (AppUtil.isNotNull(data.getString("cellphone"))) {
                    user.setCellPhone(data.getString("cellphone"));
                }
            }
            if (data.containsKey("defaultSite")) {
                if (AppUtil.isNotNull(data.getString("defaultSite"))) {
                    //user.setCellPhone(data.getString("defaultSite"));
                    //user.setAttribute(arg0, arg1, arg2)
                    String site = data.getString("defaultSite");
                    user.setAttribute("SAPME" , "DEFAULT SITE" , new String[]{site});
                }
            }


            user.save();
            user.commit();


            IRoleFactory rf = UMFactory.getRoleFactory();

            IRole role = null;

            role = UMFactory.getRoleFactory().getRoleByUniqueName("SAP_ME_USER");

            if (null != role) {
                UMFactory.getRoleFactory().addUserToRole(user.getUniqueID(), role.getUniqueID());
            }

            IUserAccountFactory accountFact = UMFactory.getUserAccountFactory();
            IUserAccount uacc = accountFact.newUserAccount(userId, user.getUniqueID());

            uacc.setPassword(password);
            uacc.setPasswordChangeRequired(true);


            uacc.created();
            uacc.save();
            uacc.commit();

            userFactory.commitUser(user, uacc);
            userFactory.invalidateCacheEntryByUniqueName(user.getUniqueID());


        } catch (UMException e) {

            throw new BusinessException(0, e.getMessage());
            //e.printStackTrace();


        }


    }

    public static List queryUserList(String username) throws BusinessException {
        List<Map> userLists = new ArrayList();
        try {
            IUserFactory userFact = UMFactory.getUserFactory();
            IUserSearchFilter userFilt = userFact.getUserSearchFilter();
            userFilt.setUniqueName("*" + username + "*" , ISearchAttribute.LIKE_OPERATOR, false);

            com.sap.security.api.ISearchResult user = UMFactory.getUserFactory().searchUsers(userFilt);
            IUserFactory userFactory = UMFactory.getUserFactory();

            while (user.hasNext()) {
                Map map = new HashMap();
                //Logic fetch the user accounts from iterator

                String uniqueid = (String) user.next();

                IUser iuser = userFactory.getUser(uniqueid);

                //IUser iuser= (IUser) user.next();
                map.put("firstName" , iuser.getFirstName());

                map.put("lastName" , iuser.getLastName());

                map.put("displayName" , iuser.getDisplayName());

                map.put("title" , iuser.getTitle());

                map.put("uniqueID" , iuser.getUniqueID());

                map.put("uniqueName" , iuser.getUniqueName());
                map.put("email" , iuser.getEmail());

                map.put("jobTitle" , iuser.getJobTitle());


                userLists.add(map);
            }

        } catch (UMException e) {
            e.printStackTrace();


        }
        return userLists;

    }

    public static boolean authUserID(String userId) throws BusinessException {

        boolean success = false;
        try {
            IUserAccountFactory uaFactory = UMFactory.getUserAccountFactory();

            IUserAccount ua = null;

            ua = uaFactory.getUserAccountByLogonId(userId);

            if (ua == null) {
                return false;
            }
            success = true;


        } catch (Exception e) {
            SimpleLogger.log(Severity.ERROR, Category.APPS_COMMON_FAILOVER,
                    Location.getLocation(Authenticate.class), "authUser" , "user authentication failed->" + userId + " reason：" + e.toString());
        }
        return success;

    }

    public static void resetMEUserPW(JSONObject data) throws BusinessException {

        if (!AppUtil.isNotNull(data.getString("id"))) {
            return;
        }

        if (!AppUtil.isNotNull(data.getString("password"))) {
            return;
        }

        String password = data.getString("password");
        String userId = data.getString("id");

        try {
            IUserAccountFactory uaFactory = UMFactory.getUserAccountFactory();

            IUserFactory userFactory = UMFactory.getUserFactory();

            IUserAccount uacc = null;

            uacc = uaFactory.getUserAccountByLogonId(userId);


            uacc.setPassword(password);
            uacc.setPasswordChangeRequired(true);
            uacc.save();
            uacc.commit();


        } catch (Exception e) {
            SimpleLogger.log(Severity.ERROR, Category.APPS_COMMON_FAILOVER,
                    Location.getLocation(Authenticate.class), "authUser" , "failed！" + e.toString());
        }

    }

    public static void removeMEUser(JSONObject data) throws BusinessException {

        if (!AppUtil.isNotNull(data.getString("id"))) {
            return;
        }

        if (!AppUtil.isNotNull(data.getString("password"))) {
            return;
        }

        String password = data.getString("password");
        String userId = data.getString("id");

        try {
            IUserAccountFactory uaFactory = UMFactory.getUserAccountFactory();

            IUserFactory userFactory = UMFactory.getUserFactory();


            IUser user = userFactory.getUserByLogonID(userId);


            uaFactory.deleteUserAccount(user.getUniqueID());

            userFactory.deleteUser(user.getUniqueID());


        } catch (Exception e) {
            SimpleLogger.log(Severity.ERROR, Category.APPS_COMMON_FAILOVER,
                    Location.getLocation(Authenticate.class), "authUser" , "failed！" + e.toString());
        }

    }

    public static boolean authUser(String userId, String password) throws BusinessException {

        boolean success = false;
        try {
            IUserAccountFactory uaFactory = UMFactory.getUserAccountFactory();

            IUserAccount ua = null;
            try {
                ua = uaFactory.getUserAccountByLogonId(userId);
            } catch (UMException e) {
                throw new AuthenticationException();
            }
            if (ua == null) {
                throw new AuthenticationException("USER[" + userId + "]Not Exist！");
            }

            int checkStatus = 0;
            try {
                checkStatus = ua.checkPasswordExtended(password);
            } catch (UMException e) {
                throw new AuthenticationException();
            }

            switch (checkStatus) {
                case ILoginConstants.CHECKPWD_OK:
                    success = true;
                default:
                    throw new AuthenticationException("Password Error！");
            }
        } catch (Exception e) {
            SimpleLogger.log(Severity.ERROR, Category.APPS_COMMON_FAILOVER,
                    Location.getLocation(Authenticate.class), "authUser" , "failed！" + e.toString());
        }
        return success;

    }

    public static JSONObject queryAttributes(String id) throws BusinessException {

        JSONObject data = new JSONObject();
        try {
            IUserFactory userFactory = UMFactory.getUserFactory();

            IUser user = userFactory.getUserByLogonID(id);


            String[] list = user.getAttributeNamespaces();
            for (String a : list) {
                String[] ss = user.getAttributeNames(a);
                //data.put(a, ss);
                for (String k : ss) {
                    String[] valus = user.getAttribute(a, k);
                    data.put(a + "_" + k, ss);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;

    }
//getAttributeNamespaces

}
