// 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 com.cloud.event;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.events.EventBus;
import org.apache.cloudstack.framework.events.EventBusException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import com.cloud.configuration.Config;
import com.cloud.event.dao.EventDao;
import com.cloud.projects.Project;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.server.ManagementService;
import com.cloud.user.Account;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.Pair;
import com.cloud.utils.ReflectUtil;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.db.EntityManager;

public class ActionEventUtils {
    private static final Logger s_logger = Logger.getLogger(ActionEventUtils.class);

    private static EventDao s_eventDao;
    private static AccountDao s_accountDao;
    private static ProjectDao s_projectDao;
    protected static UserDao s_userDao;
    protected static EventBus s_eventBus = null;
    protected static EntityManager s_entityMgr;
    protected static ConfigurationDao s_configDao;

    public static final String EventDetails = "event_details";
    public static final String EventId = "event_id";
    public static final String EntityType = "entity_type";
    public static final String EntityUuid = "entity_uuid";
    public static final String EntityDetails = "entity_details";

    @Inject
    EventDao eventDao;
    @Inject
    AccountDao accountDao;
    @Inject
    UserDao userDao;
    @Inject
    ProjectDao projectDao;
    @Inject
    EntityManager entityMgr;
    @Inject
    ConfigurationDao configDao;

    public ActionEventUtils() {
    }

    @PostConstruct
    void init() {
        s_eventDao = eventDao;
        s_accountDao = accountDao;
        s_userDao = userDao;
        s_projectDao = projectDao;
        s_entityMgr = entityMgr;
        s_configDao = configDao;
    }

    public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description, Long resourceId, String resourceType) {
        Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
        publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Completed, description, resourceDetails.second(), resourceDetails.third());
        Event event = persistActionEvent(userId, accountId, domainId, null, type, Event.State.Completed, true, description, resourceDetails.first(), resourceDetails.third(), null);
        return event.getId();
    }

    /*
     * Save event after scheduling an async job
     */
    public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) {
        Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
        publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Scheduled, description, resourceDetails.second(), resourceDetails.third());
        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId);
        return event.getId();
    }

    public static void startNestedActionEvent(String eventType, String eventDescription, Long resourceId, String resourceType) {
        CallContext.setActionEventInfo(eventType, eventDescription);
        onStartedActionEventFromContext(eventType, eventDescription, resourceId, resourceType, true);
    }

    public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) {
        CallContext ctx = CallContext.current();
        long userId = ctx.getCallingUserId();
        long accountId = ctx.getProject() != null ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId();    //This should be the entity owner id rather than the Calling User Account Id.
        long startEventId = ctx.getStartEventId();

        if (!eventType.equals(""))
            ActionEventUtils.onStartedActionEvent(userId, accountId, eventType, eventDescription, resourceId, resourceType, eventDisplayEnabled, startEventId);
    }

    /*
     * Save event after starting execution of an async job
     */
    public static Long onStartedActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) {
        Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
        publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Started, description, resourceDetails.second(), resourceDetails.third());
        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Started, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId);
        return event.getId();
    }

    public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type, String description, Long resourceId, String resourceType, long startEventId) {

        return onCompletedActionEvent(userId, accountId, level, type, true, description, resourceId, resourceType, startEventId);
    }

    public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type, boolean eventDisplayEnabled, String description, Long resourceId, String resourceType, long startEventId) {
        Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
        publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Completed, description, resourceDetails.second(), resourceDetails.third());
        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Completed, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId);
        return event.getId();

    }

    public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, boolean eventDisplayEnabled, String description, Long resourceId, String resourceType) {
        Ternary<Long, String, String> resourceDetails = getResourceDetails(resourceId, resourceType, type);
        publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Created, description, resourceDetails.second(), resourceDetails.third());
        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Created, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), null);
        return event.getId();
    }

    private static Event persistActionEvent(Long userId, Long accountId, Long domainId, String level, String type,
                                            Event.State state, boolean eventDisplayEnabled, String description,
                                            Long resourceId, String resourceType, Long startEventId) {
        EventVO event = new EventVO();
        event.setUserId(userId);
        event.setAccountId(accountId);
        event.setType(type);
        event.setState(state);
        event.setDescription(description);
        event.setDisplay(eventDisplayEnabled);

        if (domainId != null) {
            event.setDomainId(domainId);
        } else {
            event.setDomainId(getDomainId(accountId));
        }
        if (resourceId != null) {
            event.setResourceId(resourceId);
        }
        if (resourceType != null) {
            event.setResourceType(resourceType);
        }
        if (level != null && !level.isEmpty()) {
            event.setLevel(level);
        }
        if (startEventId != null) {
            event.setStartId(startEventId);
        }
        event = s_eventDao.persist(event);
        return event;
    }

    private static void publishOnEventBus(long userId, long accountId, String eventCategory, String eventType, Event.State state, String description, String resourceUuid, String resourceType) {
        String configKey = Config.PublishActionEvent.key();
        String value = s_configDao.getValue(configKey);
        boolean configValue = Boolean.parseBoolean(value);
        if(!configValue)
            return;
        try {
            s_eventBus = ComponentContext.getComponent(EventBus.class);
        } catch (NoSuchBeanDefinitionException nbe) {
            return; // no provider is configured to provide events bus, so just return
        }

        org.apache.cloudstack.framework.events.Event event =
            new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, resourceType, resourceUuid);

        Map<String, String> eventDescription = new HashMap<String, String>();
        Project project = s_projectDao.findByProjectAccountId(accountId);
        Account account = s_accountDao.findById(accountId);
        User user = s_userDao.findById(userId);
        // if account has been deleted, this might be called during cleanup of resources and results in null pointer
        if (account == null)
            return;
        if (user == null)
            return;
        if (project != null)
            eventDescription.put("project", project.getUuid());
        eventDescription.put("user", user.getUuid());
        eventDescription.put("account", account.getUuid());
        eventDescription.put("event", eventType);
        eventDescription.put("status", state.toString());
        eventDescription.put("entity", resourceType);
        eventDescription.put("entityuuid", resourceUuid);
        //Put all the first class entities that are touched during the action. For now at least put in the vmid.
        populateFirstClassEntities(eventDescription);
        eventDescription.put("description", description);

        String eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").format(new Date());
        eventDescription.put("eventDateTime", eventDate);

        event.setDescription(eventDescription);

        try {
            s_eventBus.publish(event);
        } catch (EventBusException e) {
            s_logger.warn("Failed to publish action event on the event bus.");
        }
    }

    private static Ternary<Long, String, String> getResourceDetailsUsingEntityClassAndContext(Class<?> entityClass, ApiCommandResourceType resourceType) {
        CallContext context = CallContext.current();
        ApiCommandResourceType alternateResourceType = ApiCommandResourceType.valueFromAssociatedClass(entityClass);
        if (resourceType == null ||
                (ObjectUtils.allNotNull(resourceType, alternateResourceType) &&
                        resourceType.getAssociatedClass() != alternateResourceType.getAssociatedClass())) {
            resourceType = alternateResourceType;
        }
        String entityType = resourceType == null ? entityClass.getSimpleName() : resourceType.toString();
        String entityUuid = null;
        Long entityId = null;
        Object param = context.getContextParameter(entityClass);
        if(param != null){
            try {
                entityUuid = getEntityUuid(entityClass, param);
            } catch (Exception e){
                s_logger.debug("Caught exception while finding entityUUID, moving on");
            }
        }
        if (param instanceof Long) {
            entityId = (Long)param;
        } else if (entityUuid != null) {
            Object obj = s_entityMgr.findByUuidIncludingRemoved(entityClass, entityUuid);
            if (obj instanceof InternalIdentity) {
                entityId = ((InternalIdentity)obj).getId();
            }
        }
        return new Ternary<>(entityId, entityUuid, entityType);
    }

    private static Ternary<Long, String, String> getResourceDetailsUsingEventTypeAndContext(ApiCommandResourceType resourceType, String eventType) {
        Class<?> entityClass = EventTypes.getEntityClassForEvent(eventType);
        if (entityClass != null && s_entityMgr.validEntityType(entityClass)) {
            return getResourceDetailsUsingEntityClassAndContext(entityClass, resourceType);
        } else if (resourceType != null && resourceType.getAssociatedClass() != null && s_entityMgr.validEntityType(resourceType.getAssociatedClass())) {
            return getResourceDetailsUsingEntityClassAndContext(resourceType.getAssociatedClass(), resourceType);
        }
        return new Ternary<Long, String, String>(null, null, null);
    }

    private static String getEntityUuid(Class<?> entityType, Object entityId){

        // entityId can be internal db id or UUID so accordingly call findById or return uuid directly

        if (entityId instanceof Long){
            // Its internal db id - use findById
            if (!s_entityMgr.validEntityType(entityType)) {
                return null;
            }
            final Object objVO = s_entityMgr.findByIdIncludingRemoved(entityType, (Long)entityId);
            if (objVO != null) {
                return ((Identity) objVO).getUuid();
            }
        } else if(entityId instanceof String) {
            try{
                // In case its an async job the internal db id would be a string because of json deserialization
                Long internalId = Long.valueOf((String) entityId);
                if (!s_entityMgr.validEntityType(entityType)) {
                    return null;
                }
                final Object objVO = s_entityMgr.findByIdIncludingRemoved(entityType, internalId);
                if (objVO != null) {
                    return ((Identity) objVO).getUuid();
                }
            } catch (NumberFormatException e) {
                // It is uuid - so return it
                return (String)entityId;
            }
        }

        return null;
    }

    private static Ternary<Long, String, String> updateParentResourceCases(Ternary<Long, String, String> details) {
        if (!ObjectUtils.allNotNull(details, details.first(), details.second(), details.third())) {
            return details;
        }
        HashMap<String, Pair<ApiCommandResourceType, String>> typeParentMethodMap = new HashMap<>();
        typeParentMethodMap.put(ApiCommandResourceType.VmSnapshot.toString(), new Pair<>(ApiCommandResourceType.VirtualMachine, "getVmId"));
        if (!typeParentMethodMap.containsKey(details.third())) {
            return details;
        }
        ApiCommandResourceType type = ApiCommandResourceType.fromString(details.third());
        if (type == null || !s_entityMgr.validEntityType(type.getAssociatedClass())) {
            return details;
        }
        Object objVO = s_entityMgr.findByIdIncludingRemoved(type.getAssociatedClass(), details.first());
        if (objVO == null) {
            return details;
        }
        String methodName = typeParentMethodMap.get(type.toString()).second();
        try {
            Method m = objVO.getClass().getMethod(methodName);
            Long id = (Long)m.invoke(objVO);
            if (id == null) {
                return details;
            }
            type = typeParentMethodMap.get(type.toString()).first();
            objVO = s_entityMgr.findByIdIncludingRemoved(type.getAssociatedClass(), id);
            if (objVO == null) {
                return details;
            }
            return new Ternary<>(id, ((Identity)objVO).getUuid(), type.toString());
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            s_logger.debug(String.format("Parent resource for resource ID: %d, type: %s can not be found using method %s", details.first(), type, methodName));
        }
        return details;
    }

    private static Ternary<Long, String, String> getResourceDetails(Long resourceId, String resourceType, String eventType) {
        Ternary<Long, String, String> details;
        Class<?> clazz = null;
        ApiCommandResourceType type = null;
        if (StringUtils.isNotEmpty(resourceType)) {
            type = ApiCommandResourceType.fromString(resourceType);
            if (type != null) {
                clazz = type.getAssociatedClass();
            }
        }
        if (ObjectUtils.allNotNull(resourceId, clazz)) {
            String uuid = getEntityUuid(clazz, resourceId);
            details = new Ternary<>(resourceId, uuid, resourceType);
        } else {
            details = getResourceDetailsUsingEventTypeAndContext(type, eventType);
        }
        return updateParentResourceCases(details);
    }

    private static long getDomainId(long accountId) {
        AccountVO account = s_accountDao.findByIdIncludingRemoved(accountId);
        if (account == null) {
            s_logger.error("Failed to find account(including removed ones) by id '" + accountId + "'");
            return 0;
        }
        return account.getDomainId();
    }

    private static void populateFirstClassEntities(Map<String, String> eventDescription){

        CallContext context = CallContext.current();
        Map<Object, Object> contextMap = context.getContextParameters();

        for(Map.Entry<Object, Object> entry : contextMap.entrySet()){
            try{
                Class<?> clz = (Class<?>)entry.getKey();
                if(clz != null && Identity.class.isAssignableFrom(clz)){
                    String uuid = getEntityUuid(clz, entry.getValue());
                    eventDescription.put(ReflectUtil.getEntityName(clz), uuid);
                }
            } catch (Exception e){
                s_logger.trace("Caught exception while populating first class entities for event bus, moving on");
            }
        }

    }

}
