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

import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;

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

import junit.framework.Assert;

import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;

import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.vpc.dao.PrivateIpDao;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;

//@Ignore("Requires database to be set up")
public class CreatePrivateNetworkTest {

    private static final Logger s_logger = Logger.getLogger(CreatePrivateNetworkTest.class);

    NetworkServiceImpl networkService = new NetworkServiceImpl();

    @Mock
    AccountManager _accountMgr;
    @Mock
    NetworkOfferingDao _networkOfferingDao;
    @Mock
    PhysicalNetworkDao _physicalNetworkDao;
    @Mock
    DataCenterDao _dcDao;
    @Mock
    NetworkDao _networkDao;
    @Mock
    NetworkOrchestrationService _networkMgr;
    @Mock
    PrivateIpDao _privateIpDao;

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);

        networkService._accountMgr = _accountMgr;
        networkService._networkOfferingDao = _networkOfferingDao;
        networkService._physicalNetworkDao = _physicalNetworkDao;
        networkService._dcDao = _dcDao;
        networkService._networksDao = _networkDao;
        networkService._networkMgr = _networkMgr;
        networkService._privateIpDao = _privateIpDao;

        Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
        when(networkService._accountMgr.getAccount(anyLong())).thenReturn(account);

        NetworkOfferingVO ntwkOff =
            new NetworkOfferingVO("offer", "fakeOffer", TrafficType.Guest, true, true, null, null, false, null, null, GuestType.Isolated, false, false, false, false,
                false, false, false, false, false, false, false, false, false);
        when(networkService._networkOfferingDao.findById(anyLong())).thenReturn(ntwkOff);
        List<NetworkOfferingVO> netofferlist = new ArrayList<NetworkOfferingVO>();
        netofferlist.add(ntwkOff);
        when(networkService._networkOfferingDao.listSystemNetworkOfferings()).thenReturn(netofferlist);

        PhysicalNetworkVO physicalNetwork = new PhysicalNetworkVO(1L, 1L, "2-5", "200", 1L, null, "testphysicalnetwork");
        when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);

        DataCenterVO dc = new DataCenterVO(1L, "hut", "op de hei", null, null, null, null, "10.1.1.0/24", "unreal.net", 1L, NetworkType.Advanced, null, null);
        when(networkService._dcDao.lockRow(anyLong(), anyBoolean())).thenReturn(dc);

        when(networkService._networksDao.getPrivateNetwork(anyString(), anyString(), eq(1L), eq(1L), anyLong())).thenReturn(null);

        Network net =
            new NetworkVO(1L, TrafficType.Guest, Mode.None, BroadcastDomainType.Vlan, 1L, 1L, 1L, 1L, "bla", "fake", "eet.net", GuestType.Isolated, 1L, 1L,
                ACLType.Account, false, 1L);
        when(
            networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyString(),
                eq(account), anyLong(), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), anyBoolean(), eq(1L), anyString(), anyString(),
                anyBoolean(), anyString())).thenReturn(net);

        when(networkService._privateIpDao.findByIpAndSourceNetworkId(net.getId(), "10.1.1.2")).thenReturn(null);
        when(networkService._privateIpDao.findByIpAndSourceNetworkIdAndVpcId(eq(1L), anyString(), eq(1L))).thenReturn(null);
    }

    @Test
    @DB
    public void createInvalidlyHostedPrivateNetwork() {
        TransactionLegacy __txn;
        __txn = TransactionLegacy.open("createInvalidlyHostedPrivateNetworkTest");
        /* Network nw; */
        try {
            /* nw = */
            networkService.createPrivateNetwork("bla", "fake", 1L, "vlan:1", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, true, 1L);
            /* nw = */
            networkService.createPrivateNetwork("bla", "fake", 1L, "lswitch:3", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, false, 1L);
            boolean invalid = false;
            boolean unsupported = false;
            try {
                /* nw = */
                networkService.createPrivateNetwork("bla", "fake", 1, "bla:2", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, true, 1L);
            } catch (CloudRuntimeException e) {
                Assert.assertEquals("unexpected parameter exception", "string 'bla:2' has an unknown BroadcastDomainType.", e.getMessage());
                invalid = true;
            }
            try {
                /* nw = */
                networkService.createPrivateNetwork("bla", "fake", 1, "mido://4", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, false, 1L);
            } catch (InvalidParameterValueException e) {
                Assert.assertEquals("unexpected parameter exception", "unsupported type of broadcastUri specified: mido://4", e.getMessage());
                unsupported = true;
            }
            Assert.assertEquals("'bla' should not be accepted as scheme", true, invalid);
            Assert.assertEquals("'mido' should not yet be supported as scheme", true, unsupported);
        } catch (ResourceAllocationException e) {
            s_logger.error("no resources", e);
            fail("no resources");
        } catch (ConcurrentOperationException e) {
            s_logger.error("another one is in the way", e);
            fail("another one is in the way");
        } catch (InsufficientCapacityException e) {
            s_logger.error("no capacity", e);
            fail("no capacity");
        } finally {
            __txn.close("createInvalidlyHostedPrivateNetworkTest");
        }
    }

}
