/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * Licensed 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.
 * ============LICENSE_END=========================================================
 */
package org.onap.osam.controllers;

import io.swagger.annotations.ApiOperation;
import org.onap.osam.common.dto.AccessPodDTO;
import org.onap.osam.common.dto.ChassisDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;

// TODO log
@RestController
@RequestMapping("accessPod")
public class OnapEnablerAccessPodController extends OnapEnablerController {

	private static final String ACCESS_POD = "accessPod";

	@Autowired
	public OnapEnablerAccessPodController(RestTemplate restTemplate){
		this.restTemplate = restTemplate;
	}

    @ApiOperation(value = "Get all PODs registered in OSAM Core",
            response = AccessPodDTO.class,
            responseContainer = "List")
	@RequestMapping(method = RequestMethod.GET)
	public List<AccessPodDTO> getAccessPods() {
		return Arrays.asList(restTemplate.getForObject(buildRequestPath(ACCESS_POD), AccessPodDTO[].class));
	}

    @ApiOperation(value = "Register a new POD in OSAM Core",
            response = AccessPodDTO.class)
	@RequestMapping(method = RequestMethod.POST)
	public ResponseEntity<AccessPodDTO> postAccessPod(@RequestBody AccessPodDTO accessPodDTO) {
		return restTemplate.postForEntity(buildRequestPath(ACCESS_POD), new HttpEntity<>(accessPodDTO), AccessPodDTO.class);
	}

    @ApiOperation(value = "Unregister a POD from OSAM Core by pnfId field")
    @RequestMapping(method = RequestMethod.DELETE, value = "pnf/{pnfId}")
	public void deleteAccessPodByPnfId(@PathVariable String pnfId) {
		restTemplate.delete(buildRequestPath(ACCESS_POD, "pnf", pnfId));
	}

    @ApiOperation(value = "Unregister a POD from OSAM Core by id field")
	@RequestMapping(method = RequestMethod.DELETE, value = "{id}")
	public void deleteAccessPod(@PathVariable Long id) {
		restTemplate.delete(buildRequestPath(ACCESS_POD, String.valueOf(id)));
	}



}
