// 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.user;

import com.cloud.domain.DomainVO;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.event.UsageEventVO;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.CloudException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeVO;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmManagerImpl;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VmStatsDao;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class AccountManagerImplVolumeDeleteEventTest extends AccountManagentImplTestBase {

    private static final Long ACCOUNT_ID = 1l;
    private static final String VOLUME_UUID = "vol-111111";

    @Spy
    @InjectMocks
    private UserVmManagerImpl _vmMgr;

    @Mock
    private UserVmManager userVmManager;

    @Mock
    private VmStatsDao vmStatsDaoMock;

    Map<String, Object> oldFields = new HashMap<>();
    UserVmVO vm = mock(UserVmVO.class);

    // Configures the static fields of the UsageEventUtils class, Storing the
    // previous values to be restored during the cleanup phase, to avoid
    // interference with other unit tests.
    protected UsageEventUtils setupUsageUtils() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        _usageEventDao = new MockUsageEventDao();
        UsageEventUtils utils = new UsageEventUtils();

        List<String> usageUtilsFields = new ArrayList<String>();
        usageUtilsFields.add("usageEventDao");
        usageUtilsFields.add("accountDao");
        usageUtilsFields.add("dcDao");
        usageUtilsFields.add("configDao");

        for (String fieldName : usageUtilsFields) {
            try {
                Field f = UsageEventUtils.class.getDeclaredField(fieldName);
                f.setAccessible(true);
                Field staticField = UsageEventUtils.class.getDeclaredField("s_" + fieldName);
                staticField.setAccessible(true);
                oldFields.put(f.getName(), staticField.get(null));
                f.set(utils, this.getClass().getSuperclass().getDeclaredField("_" + fieldName).get(this));
            } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
                e.printStackTrace();
            }
        }
        Method method;
        method = UsageEventUtils.class.getDeclaredMethod("init");
        method.setAccessible(true);
        method.invoke(utils);
        return utils;
    }

    protected void defineMocksBehavior() throws AgentUnavailableException, ConcurrentOperationException, CloudException {

        AccountVO account = new AccountVO();
        account.setId(ACCOUNT_ID);
        when(_accountDao.remove(ACCOUNT_ID)).thenReturn(true);
        when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);

        DomainVO domain = new DomainVO();
        VirtualMachineEntity vmEntity = mock(VirtualMachineEntity.class);

        lenient().when(_orchSrvc.getVirtualMachine(nullable(String.class))).thenReturn(vmEntity);
        lenient().when(vmEntity.destroy(nullable(Boolean.class))).thenReturn(true);

        lenient().doReturn(vm).when(_vmDao).findById(nullable(Long.class));

        VolumeVO vol = new VolumeVO(VOLUME_UUID, 1l, 1l, 1l, 1l, 1l, "folder", "path", null, 50, Type.ROOT);
        vol.setDisplayVolume(true);
        List<VolumeVO> volumes = new ArrayList<>();
        volumes.add(vol);

        lenient().when(securityChecker.checkAccess(Mockito.eq(account), nullable(ControlledEntity.class), nullable(AccessType.class), nullable(String.class))).thenReturn(true);


        lenient().when(_userVmDao.findById(nullable(Long.class))).thenReturn(vm);
        lenient().when(_userVmDao.listByAccountId(ACCOUNT_ID)).thenReturn(Arrays.asList(vm));
        lenient().when(_userVmDao.findByUuid(nullable(String.class))).thenReturn(vm);

        lenient().when(_volumeDao.findByInstance(nullable(Long.class))).thenReturn(volumes);

        ServiceOfferingVO offering = mock(ServiceOfferingVO.class);
        lenient().when(offering.getCpu()).thenReturn(500);
        lenient().when(offering.getId()).thenReturn(1l);
        lenient().when(serviceOfferingDao.findByIdIncludingRemoved(nullable(Long.class), nullable(Long.class))).thenReturn(offering);

        lenient().when(_domainMgr.getDomain(nullable(Long.class))).thenReturn(domain);

        lenient().doReturn(true).when(_vmMgr).expunge(any(UserVmVO.class));

    }

    @Before
    public void init() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, AgentUnavailableException,
    ConcurrentOperationException, CloudException {

        setupUsageUtils();
        defineMocksBehavior();
    }

    @After
    // Restores static fields of the UsageEventUtil class to previous values.
    public void cleanupUsageUtils() throws ReflectiveOperationException, SecurityException {

        UsageEventUtils utils = new UsageEventUtils();
        for (String fieldName : oldFields.keySet()) {
            Field f = UsageEventUtils.class.getDeclaredField(fieldName);
            f.setAccessible(true);
            f.set(utils, oldFields.get(fieldName));
        }
        Method method = UsageEventUtils.class.getDeclaredMethod("init");
        method.setAccessible(true);
        method.invoke(utils);
    }

    protected List<UsageEventVO> deleteUserAccountRootVolumeUsageEvents(boolean vmDestroyedPrior) throws AgentUnavailableException, ConcurrentOperationException, CloudException {

        when(vm.getState()).thenReturn(vmDestroyedPrior ? VirtualMachine.State.Destroyed : VirtualMachine.State.Running);
        lenient().when(vm.getRemoved()).thenReturn(vmDestroyedPrior ? new Date() : null);
        Mockito.doNothing().when(accountManagerImpl).checkAccess(nullable(Account.class), Mockito.isNull(), nullable(Boolean.class), nullable(Account.class));
        accountManagerImpl.deleteUserAccount(ACCOUNT_ID);

        return _usageEventDao.listAll();
    }

    @Test
    // If the VM is already destroyed, no events should get emitted
    public void destroyedVMRootVolumeUsageEvent()
            throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
        lenient().doReturn(vm).when(_vmMgr).destroyVm(nullable(Long.class), nullable(Boolean.class));
        Mockito.doNothing().when(accountManagerImpl).verifyCallerPrivilegeForUserOrAccountOperations((Account) any());
        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(true);
        Assert.assertEquals(0, emittedEvents.size());
    }

    @Ignore()
    @Test
    // If the VM is running, we should see one emitted event for the root
    // volume.
    public void runningVMRootVolumeUsageEvent()
            throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
        Mockito.doNothing().when(vmStatsDaoMock).removeAllByVmId(Mockito.anyLong());
        Mockito.when(_vmMgr.destroyVm(nullable(Long.class), nullable(Boolean.class))).thenReturn(vm);
        List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(false);
        UsageEventVO event = emittedEvents.get(0);
        Assert.assertEquals(EventTypes.EVENT_VOLUME_DELETE, event.getType());
        Assert.assertEquals(VOLUME_UUID, event.getResourceName());
    }
}
