/*
   * Method returns the Load balancer service instance running within
   * 'default' container.
   */
  private IConfigManager getConfigManagerService(String containerName) {
    IContainerManager containerManager =
        (IContainerManager) ServiceHelper.getGlobalInstance(IContainerManager.class, this);
    if (containerManager == null) {
      throw new ServiceUnavailableException(
          "Container " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    boolean found = false;
    List<String> containerNames = containerManager.getContainerNames();
    for (String cName : containerNames) {
      if (cName.trim().equalsIgnoreCase(containerName.trim())) {
        found = true;
      }
    }

    if (found == false) {
      throw new ResourceNotFoundException(
          containerName + " " + RestMessages.NOCONTAINER.toString());
    }

    IConfigManager configManager =
        (IConfigManager) ServiceHelper.getInstance(IConfigManager.class, containerName, this);

    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer" + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    return configManager;
  }
  @Path("/{containerName}/delete/pool/{poolName}")
  @DELETE
  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  @StatusCodes({
    @ResponseCode(code = 200, condition = "Pool deleted successfully"),
    @ResponseCode(code = 404, condition = "The containerName not found"),
    @ResponseCode(code = 503, condition = "Load balancer service is unavailable"),
    @ResponseCode(code = 404, condition = "Pool not found"),
    @ResponseCode(code = 500, condition = "Failed to delete Pool")
  })
  public Response deletePool(
      @PathParam(value = "containerName") String containerName,
      @PathParam(value = "poolName") String poolName) {

    if (poolName.isEmpty())
      throw new UnsupportedMediaTypeException(RestMessages.INVALIDDATA.toString());

    IConfigManager configManager = getConfigManagerService(containerName);
    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer" + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    if (!configManager.poolExists(poolName))
      throw new ResourceNotFoundException(NBConst.RES_POOL_NOT_FOUND);

    for (Pool pool : configManager.getAllPools()) {
      if (pool.getName().equals(poolName)) {
        configManager.deletePool(poolName);
        return Response.ok().build();
      }
    }
    throw new InternalServerErrorException(NBConst.RES_POOL_DELETION_FAILED);
  }
 /**
  * Returns the system control block
  *
  * @param none Identifier of the mapping
  * @return System Control Block
  *     <pre>
  *
  * Example:
  *
  * Request URL:
  * http://localhost:8080/controller/nb/v2/opendove/odmc/system
  *
  * Response body in JSON:
  * {
  *    "domain_separation": false,
  *    "snat_pool_size": 1,
  *    "egw_replication_factor": 1
  * }
  * </pre>
  */
 @GET
 @Produces({MediaType.APPLICATION_JSON})
 @StatusCodes({
   @ResponseCode(code = 200, condition = "Operation successful"),
   @ResponseCode(code = 401, condition = "Unauthorized"),
   @ResponseCode(code = 501, condition = "Not Implemented")
 })
 public Response showSubnet() {
   IfNBSystemRU systemInterface = OpenDoveNBInterfaces.getIfNBSystemRU("default", this);
   if (systemInterface == null) {
     throw new ServiceUnavailableException(
         "System RU Interface " + RestMessages.SERVICEUNAVAILABLE.toString());
   }
   return Response.status(200).entity(systemInterface.getSystemBlock()).build();
 }
  @Path("/{containerName}/create/poolmember")
  @POST
  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  @StatusCodes({
    @ResponseCode(code = 201, condition = "Pool member created successfully"),
    @ResponseCode(code = 404, condition = "The containerName not found"),
    @ResponseCode(code = 503, condition = "Load balancer service is unavailable"),
    @ResponseCode(code = 404, condition = "Pool not found"),
    @ResponseCode(code = 409, condition = "Pool member already exist"),
    @ResponseCode(code = 415, condition = "Invalid input data")
  })
  public Response addPoolMember(
      @PathParam("containerName") String containerName,
      @TypeHint(PoolMember.class) PoolMember inPoolMember) {

    PoolMember pmInput = inPoolMember;
    String name = pmInput.getName();
    String memberIP = pmInput.getIp();
    String poolName = pmInput.getPoolName();

    if (name.isEmpty() || memberIP.isEmpty() || poolName.isEmpty()) {
      throw new UnsupportedMediaTypeException(RestMessages.INVALIDDATA.toString());
    }

    IConfigManager configManager = getConfigManagerService(containerName);
    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    if (!configManager.poolExists(poolName))
      throw new ResourceNotFoundException(NBConst.RES_POOL_NOT_FOUND);

    if (!configManager.memberExists(name, memberIP, poolName)) {

      PoolMember poolMember = configManager.addPoolMember(name, memberIP, poolName);
      if (poolMember != null) {
        return Response.status(Response.Status.CREATED).build();
      }
    } else {
      throw new ResourceConflictException(NBConst.RES_POOLMEMBER_ALREADY_EXIST);
    }
    throw new InternalServerErrorException(NBConst.RES_POOLMEMBER_CREATION_FAILED);
  }
  @Path("/{containerName}/vips")
  @GET
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  @TypeHint(VIPs.class)
  @StatusCodes({
    @ResponseCode(code = 200, condition = "Operation successful"),
    @ResponseCode(code = 404, condition = "The containerName is not found"),
    @ResponseCode(code = 503, condition = "Load balancer service is unavailable")
  })
  public VIPs getAllVIPs(@PathParam("containerName") String containerName) {

    IConfigManager configManager = getConfigManagerService(containerName);
    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    return new VIPs(configManager.getAllVIPs());
  }
 /**
  * Returns all switches
  *
  * @param none
  * @return List of all switches
  *     <pre>
  *
  * Example:
  *
  * Request URL:
  * http://localhost:8080/controller/nb/v2/opendove/odmc/switches
  *
  * Response body in JSON:
  * {
  *   "switches":  [ {
  *     "id": "uuid",
  *     "name": "switch name",
  *     "tunnelip": "10.10.10.1",
  *     "mgmtip": "20.20.20.2",
  *     "timestamp": "now"
  *   } ]
  * }
  * </pre>
  */
 @GET
 @Produces({MediaType.APPLICATION_JSON})
 @TypeHint(OpenDoveSwitchRequest.class)
 @StatusCodes({
   @ResponseCode(code = 200, condition = "Operation successful"),
   @ResponseCode(code = 204, condition = "No content"),
   @ResponseCode(code = 401, condition = "Unauthorized"),
   @ResponseCode(code = 500, condition = "Internal Error")
 })
 public Response showServiceAppliances() {
   IfOpenDoveSwitchCRUD sbInterface = OpenDoveCRUDInterfaces.getIfOpenDoveSwitchCRU(this);
   if (sbInterface == null) {
     throw new ServiceUnavailableException(
         "OpenDove SB Interface " + RestMessages.SERVICEUNAVAILABLE.toString());
   }
   return Response.status(200)
       .entity(new OpenDoveSwitchRequest(sbInterface.getSwitches()))
       .build();
 }
  /**
   * Updates the control block
   *
   * @param input system control block in patch format
   * @return Updated System Control Block
   *     <pre>
   *
   * Example:
   *
   * Request URL:
   * http://localhost:8080/controller/nb/v2/opendove/odmc/system
   *
   * Request body in JSON:
   * {
   *    "domain_separation": true
   * }
   *
   * Response body in JSON:
   * {
   *    "domain_separation": true,
   *    "snat_pool_size": 1,
   *    "egw_replication_factor": 1
   * }
   * </pre>
   */
  @PUT
  @Produces({MediaType.APPLICATION_JSON})
  @Consumes({MediaType.APPLICATION_JSON})
  @StatusCodes({
    @ResponseCode(code = 200, condition = "Operation successful"),
    @ResponseCode(code = 400, condition = "Bad Request"),
    @ResponseCode(code = 401, condition = "Unauthorized"),
    @ResponseCode(code = 501, condition = "Not Implemented")
  })
  public Response updateSubnet(final OpenDoveNeutronControlBlock input) {
    IfNBSystemRU systemInterface = OpenDoveNBInterfaces.getIfNBSystemRU("default", this);
    if (systemInterface == null) {
      throw new ServiceUnavailableException(
          "System RU Interface " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    // update network object and return the modified object
    systemInterface.updateControlBlock(input);
    return Response.status(200).entity(systemInterface.getSystemBlock()).build();
  }
  @Path("/{containerName}/create/vip")
  @POST
  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  @StatusCodes({
    @ResponseCode(code = 201, condition = "VIP created successfully"),
    @ResponseCode(code = 404, condition = "The Container Name not found"),
    @ResponseCode(code = 503, condition = "Load balancer service is unavailable"),
    @ResponseCode(code = 409, condition = "VIP already exist"),
    @ResponseCode(code = 415, condition = "Invalid input data")
  })
  public Response addVIP(
      @PathParam("containerName") String containerName, @TypeHint(VIP.class) VIP inVIP) {

    VIP vipInput = inVIP;
    String name = vipInput.getName();
    String ip = vipInput.getIp();
    String protocol = vipInput.getProtocol();
    short protocolPort = vipInput.getPort();
    String poolName = vipInput.getPoolName();
    if (name.isEmpty() || ip.isEmpty() || protocol.isEmpty() || protocolPort < 0) {
      throw new UnsupportedMediaTypeException(RestMessages.INVALIDDATA.toString());
    }

    IConfigManager configManager = getConfigManagerService(containerName);

    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    if (!configManager.vipExists(name, ip, protocol, protocolPort, poolName)) {

      VIP vip = configManager.createVIP(name, ip, protocol, protocolPort, poolName);
      if (vip != null) {
        return Response.status(Response.Status.CREATED).build();
      }
    } else {
      throw new ResourceConflictException(NBConst.RES_VIP_ALREADY_EXIST);
    }
    throw new InternalServerErrorException(NBConst.RES_VIP_CREATION_FAILED);
  }
  @Path("/{containerName}/update/vip")
  @PUT
  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  @StatusCodes({
    @ResponseCode(code = 201, condition = "VIP updated successfully"),
    @ResponseCode(code = 404, condition = "The containerName not found"),
    @ResponseCode(code = 503, condition = "VIP not found"),
    @ResponseCode(code = 404, condition = "Pool not found"),
    @ResponseCode(code = 405, condition = "Pool already attached to the VIP"),
    @ResponseCode(code = 415, condition = "Invalid input name")
  })
  public Response updateVIP(
      @PathParam("containerName") String containerName, @TypeHint(VIP.class) VIP inVIP) {

    VIP vipInput = inVIP;
    String name = vipInput.getName();
    String poolName = vipInput.getPoolName();
    if (name.isEmpty() || poolName.isEmpty()) {
      throw new UnsupportedMediaTypeException(RestMessages.INVALIDDATA.toString());
    }

    IConfigManager configManager = getConfigManagerService(containerName);
    if (configManager == null) {
      throw new ServiceUnavailableException(
          "Load Balancer " + RestMessages.SERVICEUNAVAILABLE.toString());
    }

    if (!configManager.poolExists(poolName))
      throw new ResourceNotFoundException(NBConst.RES_POOL_NOT_FOUND);

    if (configManager.getVIPAttachedPool(name) != null)
      throw new MethodNotAllowedException(NBConst.RES_VIP_POOL_EXIST);

    if (configManager.updateVIP(name, poolName) != null)
      return Response.status(Response.Status.ACCEPTED).build();

    throw new InternalServerErrorException(NBConst.RES_VIP_UPDATE_FAILED);
  }
 /**
  * Returns a particular switch
  *
  * @param switchUUID Identifier of the switch
  * @return Data on that switch
  *     <pre>
  *
  * Example:
  *
  * Request URL:
  * http://localhost:8080/controller/nb/v2/opendove/odmc/switches/uuid
  *
  * Response body in JSON:
  * {
  *   "switch": {
  *     "id": "uuid",
  *     "name": "switch name",
  *     "tunnelip": "10.10.10.1",
  *     "mgmtip": "20.20.20.2",
  *     "timestamp": "now"
  *   }
  * }
  * </pre>
  */
 @Path("{switchUUID}")
 @GET
 @Produces({MediaType.APPLICATION_JSON})
 @TypeHint(OpenDoveSwitchRequest.class)
 @StatusCodes({
   @ResponseCode(code = 200, condition = "Operation successful"),
   @ResponseCode(code = 204, condition = "No content"),
   @ResponseCode(code = 401, condition = "Unauthorized"),
   @ResponseCode(code = 404, condition = "Not Found"),
   @ResponseCode(code = 500, condition = "Internal Error")
 })
 public Response showSwtich(@PathParam("switchUUID") String switchUUID) {
   IfOpenDoveSwitchCRUD sbInterface = OpenDoveCRUDInterfaces.getIfOpenDoveSwitchCRU(this);
   if (sbInterface == null) {
     throw new ServiceUnavailableException(
         "OpenDove SB Interface " + RestMessages.SERVICEUNAVAILABLE.toString());
   }
   if (!sbInterface.switchExists(switchUUID)) {
     throw new ResourceNotFoundException("Switch doesn't exist");
   }
   return Response.status(200)
       .entity(new OpenDoveSwitchRequest(sbInterface.getSwitch(switchUUID)))
       .build();
 }