/*-
 * ============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 org.onap.osam.exceptions.OperationNotAllowedException;
import org.onap.osam.model.ExceptionResponse;

import org.onap.osam.model.JobAuditStatus;
import org.onap.osam.model.ServiceInfo;
import org.onap.osam.model.serviceInstantiation.ServiceInstantiation;
import org.onap.osam.mso.MsoResponseWrapper2;
import org.onap.osam.services.IAsyncInstantiationBusinessLogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED;


@RestController
@RequestMapping(AsyncInstantiationController.ASYNC_INSTANTIATION)
public class AsyncInstantiationController extends OsamCoreRestrictedBaseController {

    public static final String ASYNC_INSTANTIATION = "asyncInstantiation";

    protected final IAsyncInstantiationBusinessLogic asyncInstantiationBL;

    @Autowired
    public AsyncInstantiationController(IAsyncInstantiationBusinessLogic asyncInstantiationBL) {
        this.asyncInstantiationBL = asyncInstantiationBL;
    }

    @ExceptionHandler(OperationNotAllowedException.class)
    @ResponseStatus(value=METHOD_NOT_ALLOWED)
    public ExceptionResponse illegalStateExceptionHandler(Exception e) {
        return ControllersUtils.handleException(e, LOGGER);
    }

    @RequestMapping(method = RequestMethod.GET)
    public List<ServiceInfo> getServicesInfo(HttpServletRequest request) {
        return asyncInstantiationBL.getAllServicesInfo();
    }

    @RequestMapping(value = "bulk", method = RequestMethod.POST)
    public MsoResponseWrapper2<List<String>> createBulkOfServices(@RequestBody ServiceInstantiation request, HttpServletRequest httpServletRequest) {
        //Push to DB according the model

        String userId = ControllersUtils.extractUserId(httpServletRequest);
        List<UUID> uuids =  asyncInstantiationBL.pushBulkJob(request, userId);

        return new MsoResponseWrapper2(200, uuids);
    }

    @RequestMapping(value = "job/{jobId}", method = RequestMethod.DELETE)
    public void deleteServiceInfo(@PathVariable("jobId") UUID jobId) {
        asyncInstantiationBL.deleteJob(jobId);
    }

    @RequestMapping(value = "hide/{jobId}", method = RequestMethod.POST)
    public void hideServiceInfo(@PathVariable("jobId") UUID jobId) {
        asyncInstantiationBL.hideServiceInfo(jobId);
    }

    @RequestMapping(value = "auditStatus/{jobId}", method = RequestMethod.GET)
    public List<JobAuditStatus> getJobAuditStatus(HttpServletRequest request, @PathVariable(value="jobId") UUID jobId, @RequestParam(value="source") JobAuditStatus.SourceStatus source){
        return asyncInstantiationBL.getAuditStatuses(jobId, source);
    }


}
