/*-
 * ============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.job.command;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import io.joshworks.restclient.http.HttpResponse;
import org.onap.osam.services.IAsyncInstantiationBusinessLogic;
import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
import org.onap.osam.aai.exceptions.InvalidAAIResponseException;
import org.onap.osam.exceptions.MaxRetriesException;
import org.onap.osam.job.Job;
import org.onap.osam.job.JobCommand;
import org.onap.osam.job.NextCommand;
import org.onap.osam.model.RequestReferencesContainer;
import org.onap.osam.model.serviceInstantiation.ServiceInstantiation;
import org.onap.osam.mso.MsoInterface;
import org.onap.osam.mso.rest.RequestDetailsWrapper;
import org.onap.osam.services.IAuditService;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.Map;
import java.util.UUID;


@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ServiceInstantiationCommand implements JobCommand {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(ServiceInstantiationCommand.class);

    @Inject
    private IAsyncInstantiationBusinessLogic asyncInstantiationBL;

    @Inject
    private IAuditService auditService;

    @Inject
    private MsoInterface restMso;

    private UUID uuid;
    private ServiceInstantiation serviceInstantiationRequest;
    private String userId;

    public ServiceInstantiationCommand() {
    }

    public ServiceInstantiationCommand(UUID uuid, ServiceInstantiation serviceInstantiationRequest, String userId) {
        init(uuid, serviceInstantiationRequest, userId);
    }

    @Override
    public NextCommand call() {
        RequestDetailsWrapper requestDetailsWrapper = new RequestDetailsWrapper();
        try {
            /*requestDetailsWrapper = asyncInstantiationBL.generateServiceInstantiationRequest(
                    uuid, serviceInstantiationRequest, userId
            );*/
        }

        //Aai return bad response while checking names uniqueness
        catch (InvalidAAIResponseException exception) {
            LOGGER.error("Failed to check name uniqueness in AAI. VID will try again later", exception);
            //put the job in_progress so we will keep trying to check name uniqueness in AAI
            //And then send the request to MSO
            return new NextCommand(Job.JobStatus.IN_PROGRESS, this);
        }

        //Vid reached to max retries while trying to find unique name in AAI
        catch (MaxRetriesException exception) {
            LOGGER.error("Failed to find unused name in AAI. Set the job to FAILED ", exception);
            return handleCommandFailed();
        }

        String path = asyncInstantiationBL.getServiceInstantiationPath(serviceInstantiationRequest);

        HttpResponse<RequestReferencesContainer> msoResponse = restMso.post(path,
            requestDetailsWrapper, RequestReferencesContainer.class);


        if (msoResponse.getStatus() >= 200 && msoResponse.getStatus() < 400) {
            final Job.JobStatus jobStatus = Job.JobStatus.IN_PROGRESS;
            final String requestId = msoResponse.getBody().getRequestReferences().getRequestId();
            final String instanceId = msoResponse.getBody().getRequestReferences().getInstanceId();
            asyncInstantiationBL.auditVidStatus(uuid, jobStatus);
            setInitialRequestAuditStatusFromMso(requestId);
            asyncInstantiationBL.updateServiceInfo(uuid, x-> {
                x.setJobStatus(jobStatus);
                x.setServiceInstanceId(instanceId);
            });

            return new NextCommand(jobStatus, new InProgressStatusCommand(uuid, requestId));
        } else {
            auditService.setFailedAuditStatusFromMso(uuid,null, msoResponse.getStatus(),
                msoResponse.getBody().toString());
            return handleCommandFailed();
        }

    }

    private void setInitialRequestAuditStatusFromMso(String requestId){
        final String initialMsoRequestStatus = "REQUESTED";
        asyncInstantiationBL.auditMsoStatus(uuid,initialMsoRequestStatus,requestId,null);
    }

    protected NextCommand handleCommandFailed() {
        asyncInstantiationBL.handleFailedInstantiation(uuid);
        return new NextCommand(Job.JobStatus.FAILED);
    }

    @Override
    public ServiceInstantiationCommand init(UUID jobUuid, Map<String, Object> data) {
        final Object request = data.get("request");

        return init(
                jobUuid,
                OBJECT_MAPPER.convertValue(request, ServiceInstantiation.class),
                (String) data.get("userId")
        );
    }

    private ServiceInstantiationCommand init(UUID jobUuid, ServiceInstantiation serviceInstantiationRequest, String userId) {
        this.uuid = jobUuid;
        this.serviceInstantiationRequest = serviceInstantiationRequest;
        this.userId = userId;

        return this;
    }

    @Override
    public Map<String, Object> getData() {
        return ImmutableMap.of(
                "uuid", uuid,
                "request", serviceInstantiationRequest,
                "userId", userId
        );
    }
}
