package org.ovirt.engine.core.bll;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.ovirt.engine.core.common.action.AddVmTemplateParameters;
import org.ovirt.engine.core.common.businessentities.ArchitectureType;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VMStatus;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.common.errors.VdcBllMessages;
import org.ovirt.engine.core.common.osinfo.OsRepository;
import org.ovirt.engine.core.common.utils.SimpleDependecyInjector;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.dao.VdsGroupDAO;
import org.ovirt.engine.core.dao.VmDAO;
import org.ovirt.engine.core.utils.MockConfigRule;

/** A test case for {@link AddVmTemplateCommand} */
@RunWith(MockitoJUnitRunner.class)
public class AddVmTemplateCommandTest {

    private AddVmTemplateCommand<AddVmTemplateParameters> cmd;
    private VM vm;
    private VDSGroup vdsGroup;
    @Mock
    private VmDAO vmDao;

    @Mock
    private VdsGroupDAO vdsGroupDao;

    @Mock
    private OsRepository osRepository;

    @ClassRule
    public static MockConfigRule mcr = new MockConfigRule(mockConfig(ConfigValues.VmPriorityMaxValue, 100));

    @Before
    public void setUp() {
        // The VM to use
        Guid vmId = Guid.newGuid();
        Guid vdsGroupId = Guid.newGuid();
        Guid spId = Guid.newGuid();

        vm = new VM();
        vm.setId(vmId);
        vm.setVdsGroupId(vdsGroupId);
        vm.setStoragePoolId(spId);
        vm.setVmOs(14);
        when(vmDao.get(vmId)).thenReturn(vm);

        // The cluster to use
        vdsGroup = new VDSGroup();
        vdsGroup.setcpu_name("Intel Conroe Family");
        vdsGroup.setArchitecture(ArchitectureType.x86_64);
        vdsGroup.setId(vdsGroupId);
        vdsGroup.setStoragePoolId(spId);
        vdsGroup.setcompatibility_version(Version.v3_2);
        when(vdsGroupDao.get(vdsGroupId)).thenReturn(vdsGroup);
        when(osRepository.getMinimumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(0);
        when(osRepository.getMaximumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(100);
        when(osRepository.getArchitectureFromOS(14)).thenReturn(ArchitectureType.x86_64);
        AddVmTemplateParameters params = new AddVmTemplateParameters(vm, "templateName", "Template for testing");

        // init the injector with the osRepository instance
        SimpleDependecyInjector.getInstance().bind(OsRepository.class, osRepository);

        // Using the compensation constructor since the normal one contains DB access
        cmd = spy(new AddVmTemplateCommand<AddVmTemplateParameters>(params) {

            @Override
            protected void updateVmDisks() {
            }

            @Override
            protected void updateVmDevices() {
            }

            @Override
            public VM getVm() {
                return vm;
            }
        });
        doReturn(vmDao).when(cmd).getVmDAO();
        doReturn(vdsGroupDao).when(cmd).getVdsGroupDAO();
        cmd.setVmId(vmId);
        cmd.setVdsGroupId(vdsGroupId);
    }

    @Test
    public void testCanDoAction() {
        doReturn(true).when(cmd).validateVmNotDuringSnapshot();
        vm.setStatus(VMStatus.Up);

        CanDoActionTestUtils.runAndAssertCanDoActionFailure(cmd, VdcBllMessages.VMT_CANNOT_CREATE_TEMPLATE_FROM_DOWN_VM);
    }

    @Test
    public void testBeanValidations() {
        assertTrue(cmd.validateInputs());
    }

    @Test
    public void testPatternBasedNameFails() {
        cmd.getParameters().setName("aa-??bb");
        assertFalse("Pattern-based name should not be supported for Template", cmd.validateInputs());
    }
}

@@ -2533,522 +2533,140 @@
     
-when(osRepository.getMinimumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(0);%0A        when(osRepository.getMaximumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(100);%0A        when(osRepository.getArchitectureFromOS(14)).thenReturn(ArchitectureType.x86_64);%0A        AddVmTemplateParameters params = new AddVmTemplateParameters(vm, %22templateName%22, %22Template for testing%22);%0A%0A        // init the injector with the osRepository instance%0A        SimpleDependecyInjector.getInstance().bind(OsRepository.class, osRepository
+AddVmTemplateParameters params = new AddVmTemplateParameters(vm, %22templateName%22, %22Template for testing%22);%0A%0A        mockOsRepository(
 );%0A%0A
@@ -3272,32 +3272,513 @@
 roupId);%0A    %7D%0A%0A
+    protected void mockOsRepository() %7B%0A        SimpleDependecyInjector.getInstance().bind(OsRepository.class, osRepository);%0A        VmHandler.init();%0A        when(osRepository.isWindows(0)).thenReturn(true);%0A        when(osRepository.getMinimumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(0);%0A        when(osRepository.getMaximumRam(vm.getVmOsId(), Version.v3_2)).thenReturn(100);%0A        when(osRepository.getArchitectureFromOS(14)).thenReturn(ArchitectureType.x86_64);%0A    %7D%0A%0A
     @Test%0A    pu

fix osRepository NPE in AddVmTemplateCommandTest