// 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 com.cloud.api.commands.UpgradeRouterCmd;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.router.VirtualRouter;

public interface VirtualNetworkApplianceService {
    /**
     * Starts domain router
     * 
     * @param cmd
     *            the command specifying router's id
     * @return DomainRouter object
     */
    VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, 
    ResourceUnavailableException, InsufficientCapacityException;

    /**
     * Reboots domain router
     * 
     * @param cmd
     *            the command specifying router's id
     * @return router if successful
     */
    VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, 
    ResourceUnavailableException, InsufficientCapacityException;

    VirtualRouter upgradeRouter(UpgradeRouterCmd cmd);

    /**
     * Stops domain router
     * 
     * @param id
     *            of the router
     * @param forced
     *            just do it. caller knows best.
     * @return router if successful, null otherwise
     * @throws ResourceUnavailableException
     * @throws ConcurrentOperationException
     */
    VirtualRouter stopRouter(long routerId, boolean forced) throws ResourceUnavailableException, ConcurrentOperationException;

    VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException;

    VirtualRouter destroyRouter(long routerId) throws ResourceUnavailableException, ConcurrentOperationException;

}
