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

import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/VpcTestContext.xml")
public class Site2SiteVpnTest {
    private final static Logger s_logger = Logger.getLogger(Site2SiteVpnTest.class);

//    private static void addDaos(MockComponentLocator locator) {
//        locator.addDao("AccountDao", AccountDaoImpl.class);
//        locator.addDao("Site2SiteCustomerGatewayDao", Site2SiteCustomerGatewayDaoImpl.class);
//        locator.addDao("Site2SiteVpnGatewayDao", Site2SiteVpnGatewayDaoImpl.class);
//        locator.addDao("Site2SiteVpnConnectionDao", Site2SiteVpnConnectionDaoImpl.class);
//
//        locator.addDao("IPAddressDao", IPAddressDaoImpl.class);
//        locator.addDao("VpcDao", VpcDaoImpl.class);
//        locator.addDao("ConfiguratioDao", MockConfigurationDaoImpl.class);
//
//    }
//
//    private static void addManagers(MockComponentLocator locator) {
//        locator.addManager("AccountManager", MockAccountManagerImpl.class);
//        locator.addManager("VpcManager", MockVpcManagerImpl.class);
//    }

    @Before
    public void setUp() {
//        locator = new MockComponentLocator("management-server");
//        addDaos(locator);
//        addManagers(locator);
//        s_logger.info("Finished setUp");
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testInjected() throws Exception {
//        List<Pair<String, Class<? extends Site2SiteVpnServiceProvider>>> list =
//                new ArrayList<Pair<String, Class<? extends Site2SiteVpnServiceProvider>>>();
//        list.add(new Pair<String, Class<? extends Site2SiteVpnServiceProvider>>("Site2SiteVpnServiceProvider", MockSite2SiteVpnServiceProvider.class));
//        locator.addAdapterChain(Site2SiteVpnServiceProvider.class, list);
//        s_logger.info("Finished add adapter");
//        locator.makeActive(new DefaultInterceptorLibrary());
//        s_logger.info("Finished make active");
//        Site2SiteVpnManagerImpl vpnMgr = ComponentLocator.inject(Site2SiteVpnManagerImpl.class);
//        s_logger.info("Finished inject");
//        Assert.assertTrue(vpnMgr.configure("Site2SiteVpnMgr",new HashMap<String, Object>()) );
//        Assert.assertTrue(vpnMgr.start());

    }

}
