/*-
 * ============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.demo;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.onap.osam.job.command.WatchingCommand;
import org.onap.osam.job.dao.job.JobStatus;
import org.onap.osam.job.IJobCommand;
import org.onap.osam.job.JobType;
import org.onap.osam.job.NextCommand;
import org.onap.osam.job.command.CommandBase;
import org.onap.osam.job.impl.DummyAsyncRequest;
import org.onap.osam.job.impl.JobFactory;
import org.onap.osam.job.impl.JobSharedData;
import org.onap.osam.job.impl.JobsDataAccessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

/**
 * In this example, Chassis job is successful and spawns off OLT job - without being dependent on it.
 */

public class ChassisCommand extends CommandBase implements IJobCommand {

    private Boolean isSuccessful;

    private Boolean isOltDependant;

    @Autowired
    protected JobsDataAccessService jobsDataAccessService;

    @Autowired
    protected JobFactory jobFactory;

    public ChassisCommand(){}

    @Override
    public IJobCommand init(JobSharedData sharedData, Map<String, Object> commandData) {
        super.init(sharedData);
        isSuccessful = (Boolean) commandData.get("isSuccessful");
        isOltDependant = (Boolean) commandData.get("isOltDependant");
        return this;
    }

    @Override
    public Map<String, Object> getData() {
        return ImmutableMap.of("isSuccessful", isSuccessful,
                "isOltDependant", isOltDependant);
    }

    @Override
    public NextCommand call() {
        NextCommand nextCommand;
        if (isSuccessful){
            log.debug("ChassisCommand - it's your LUCKY day! :) ChassisCreation created, continuing to OLTCreation...");

            //Adding an OLTCreation child job
            final List<UUID> oltChildJobs = getOltChildJobs();

            if (isOltDependant){
                log.debug("ChassisCommand - OLT Dependent scenario. Pending to wait if OLT job succeeds before deciding if Chassis job succeeds.");
                nextCommand = new NextCommand(JobStatus.PENDING, new WatchingCommand(getSharedData(), oltChildJobs, true));
            } else {
                log.debug("ChassisCommand - independent scenario. This job is completed, regardless of child OLT job.");
                nextCommand = new NextCommand(JobStatus.COMPLETED);
            }
         } else {
            log.debug("ChassisCommand - it's your UNLUCKY day! :( ChassisCreation creation failed, your bulk request is finished here.");
            nextCommand = new NextCommand(JobStatus.FAILED);
        }
        return nextCommand;
    }

    private List<UUID> getOltChildJobs() {
        log.debug("Spinning off OLT child job....");
        Map<String, Object> dataForOLTChild = ImmutableMap.of();
        return Lists.newArrayList(jobsDataAccessService.add(jobFactory.createChildJob(JobType.OLTCreation, JobStatus.CREATING, new DummyAsyncRequest(), getSharedData(), ImmutableMap.of())));
    }
}
