/*-
 * ============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 lombok.extern.slf4j.Slf4j;
import org.onap.osam.job.dao.job.JobStatus;
import org.onap.osam.job.dao.job.OsamJob;
import org.onap.osam.job.IJobCommand;
import org.onap.osam.job.NextCommand;
import org.onap.osam.job.AsyncJobService;
import org.onap.osam.job.impl.JobSharedData;
import org.onap.osam.job.repository.job.OsamJobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
public abstract class BaseWatchingCommand extends CommandBase implements IJobCommand {

    @Autowired
    protected AsyncJobService asyncInstantiationBL;

    @Autowired
    private OsamJobRepository osamJobRepository;

    private List<UUID> childrenJobsIds;

    protected boolean isRoot;

    public BaseWatchingCommand() {}

    public BaseWatchingCommand(JobSharedData sharedData, List<UUID> childrenJobsIds, boolean isRoot) {
        init(sharedData, childrenJobsIds, isRoot);
    }

    @Override
    public BaseWatchingCommand init(JobSharedData sharedData, Map<String, Object> commandData) {
        return init(
                sharedData,
                ((List<String>) commandData.get("childrenJobs")).stream().map(x -> UUID.fromString(x)).collect(Collectors.toList()),
                (boolean) commandData.get("isRoot")
        );
    }

    protected BaseWatchingCommand init(JobSharedData sharedData, List<UUID> childrenJobsIds, boolean isRoot) {
        super.init(sharedData);
        this.childrenJobsIds = CollectionUtils.isEmpty(childrenJobsIds) ? new ArrayList<>() : childrenJobsIds;
        this.isRoot = isRoot;
        return this;
    }

    @Override
    public NextCommand call() {
        Map<UUID, OsamJob> jobs = getAllChildrenJobs();

        boolean isAllChildrenFinal = true;
        boolean hasFailedChild = false;
        for (UUID jobId: childrenJobsIds) {
            OsamJob job = jobs.get(jobId);


            //if job not found - we assume it failed
            if (job == null || job.getStatus() == null) {
                hasFailedChild = true;
                continue;
            }

            if (!job.getStatus().isFinal()) {
                isAllChildrenFinal = false;
            } else if (!job.getStatus().equals(JobStatus.COMPLETED)) {
                //if job status is final - check if it failed status
                hasFailedChild = true;
            }
        }

        return getNextCommand(isAllChildrenFinal, hasFailedChild);
    }

    private Map<UUID, OsamJob> getAllChildrenJobs() {
        List<OsamJob> jobs = osamJobRepository.findAllByUuid(childrenJobsIds);
        return jobs.stream().collect(Collectors.toMap(OsamJob::getUuid, item -> item));
    }

    protected abstract NextCommand getNextCommand(boolean isAllChildrenFinal, boolean hasFailedChild);


    @Override
    public Map<String, Object> getData() {
        Map<String, Object> data = new HashMap<>();
        data.put("childrenJobs", childrenJobsIds);
        data.put("isRoot", isRoot);
        return data;
    }
}
