// 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.network.lb;

import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.NetworkModelImpl;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVMMapVO;
import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.RulesManagerImpl;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.uservm.UserVm;
import com.cloud.vm.Nic;
import com.cloud.vm.NicVO;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.UserVmDao;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;

import javax.inject.Inject;

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

import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

public class AssignLoadBalancerTest {

    @Inject
    AccountManager _accountMgr;

    @Inject
    AccountManager _acctMgr;

    @Inject
    AccountDao _accountDao;

    @Inject
    DomainDao _domainDao;

    @Mock
    List<LoadBalancerVMMapVO> _lbvmMapList;

    @Mock
    List<Nic> nic;

    @Mock
    UserVmDao userDao;

    @Spy
    RulesManagerImpl _rulesMgr = new RulesManagerImpl() {
        @Override
        public void checkRuleAndUserVm (FirewallRule rule, UserVm userVm, Account caller) {

        }
    };


    @Spy
    NicVO nicvo = new NicVO() {

    };

    @Spy
    NetworkModelImpl _networkModel = new NetworkModelImpl() {
        @Override
        public List<? extends Nic> getNics(long vmId) {
            nic = new ArrayList<Nic>();
            nicvo.setNetworkId(204L);
            nic.add(nicvo);
            return nic;
        }
    };


    LoadBalancingRulesManagerImpl _lbMgr = new LoadBalancingRulesManagerImpl();

    private AssignToLoadBalancerRuleCmd assignToLbRuleCmd;
    private ResponseGenerator responseGenerator;
    private SuccessResponse successResponseGenerator;

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private static long domainId = 5L;
    private static long accountId = 5L;
    private static String accountName = "admin";

    @Before
    public void setUp() {
        assignToLbRuleCmd = new AssignToLoadBalancerRuleCmd() {
        };

        // ComponentContext.initComponentsLifeCycle();
        AccountVO account = new AccountVO(accountName, domainId, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
        DomainVO domain = new DomainVO("rootDomain", 5L, 5L, "networkDomain");

        UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());

        CallContext.register(user, account);

    }

    @Test(expected = InvalidParameterValueException.class)
    public void testBothArgsEmpty() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException {

        Map<Long, List<String>> emptyMap = new HashMap<Long, List<String>>();

        LoadBalancerDao lbdao = Mockito.mock(LoadBalancerDao.class);
        _lbMgr._lbDao =  lbdao;

        when(lbdao.findById(anyLong())).thenReturn(Mockito.mock(LoadBalancerVO.class));

        _lbMgr.assignToLoadBalancer(1L, null, emptyMap);

    }

    @Test(expected = InvalidParameterValueException.class)
    public void testNicIsNotInNw() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException {

        Map<Long, List<String>> vmIdIpMap = new HashMap<Long, List<String>>();
        List<String> secIp = new ArrayList<String>();
        secIp.add("10.1.1.175");
        vmIdIpMap.put(1L,secIp);

        List<Long> vmIds = new ArrayList<Long>();
        vmIds.add(2L);

        LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
        LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
        UserVmDao userVmDao = Mockito.mock(UserVmDao.class);

        _lbMgr._lbDao = lbDao;
        _lbMgr._lb2VmMapDao = lb2VmMapDao;
        _lbMgr._vmDao = userVmDao;
        _lbvmMapList = new ArrayList<>();
        _lbMgr._rulesMgr = _rulesMgr;
        _lbMgr._networkModel = _networkModel;

        when(lbDao.findById(anyLong())).thenReturn(Mockito.mock(LoadBalancerVO.class));
        when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
        when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);

        _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap);
    }


    @Test(expected = InvalidParameterValueException.class)
    public void tesSecIpNotSetToVm() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException {

        AssignToLoadBalancerRuleCmd assignLbRuleCmd = Mockito.mock(AssignToLoadBalancerRuleCmd.class);

        Map<Long, List<String>> vmIdIpMap = new HashMap<Long, List<String>>();
        List<String> secIp = new ArrayList<String>();
        secIp.add("10.1.1.175");
        vmIdIpMap.put(1L,secIp);

        List<Long> vmIds = new ArrayList<Long>();
        vmIds.add(2L);

        LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp");

        LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
        LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
        UserVmDao userVmDao = Mockito.mock(UserVmDao.class);
        NicSecondaryIpDao nicSecIpDao =  Mockito.mock(NicSecondaryIpDao.class);

        _lbMgr._lbDao = lbDao;
        _lbMgr._lb2VmMapDao = lb2VmMapDao;
        _lbMgr._vmDao = userVmDao;
        _lbMgr._nicSecondaryIpDao = nicSecIpDao;
        _lbvmMapList = new ArrayList<>();
        _lbMgr._rulesMgr = _rulesMgr;
        _lbMgr._networkModel = _networkModel;

        when(lbDao.findById(anyLong())).thenReturn(lbVO);
        when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
        when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);
        when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null);

        _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap);
    }



    @Test(expected = InvalidParameterValueException.class)
    public void testVmIdAlreadyExist() throws ResourceAllocationException, ResourceUnavailableException, InsufficientCapacityException {

        AssignToLoadBalancerRuleCmd assignLbRuleCmd = Mockito.mock(AssignToLoadBalancerRuleCmd.class);

        Map<Long, List<String>> vmIdIpMap = new HashMap<Long, List<String>>();
        List<String> secIp = new ArrayList<String>();
        secIp.add("10.1.1.175");
        vmIdIpMap.put(1L,secIp);

        List<Long> vmIds = new ArrayList<Long>();
        vmIds.add(2L);

        LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp");

        LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
        LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
        UserVmDao userVmDao = Mockito.mock(UserVmDao.class);
        NicSecondaryIpDao nicSecIpDao =  Mockito.mock(NicSecondaryIpDao.class);
        LoadBalancerVMMapVO lbVmMapVO = new LoadBalancerVMMapVO(1L, 1L, "10.1.1.175", false);

        _lbMgr._lbDao = lbDao;
        _lbMgr._lb2VmMapDao = lb2VmMapDao;
        _lbMgr._vmDao = userVmDao;
        _lbMgr._nicSecondaryIpDao = nicSecIpDao;
        _lbvmMapList = new ArrayList<>();
        _lbvmMapList.add(lbVmMapVO);
        _lbMgr._rulesMgr = _rulesMgr;
        _lbMgr._networkModel = _networkModel;

        when(lbDao.findById(anyLong())).thenReturn(lbVO);
        when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
        when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);
        when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null);

        _lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap);
    }

    @After
    public void tearDown() {
        CallContext.unregister();
    }

}