/*-
 * ============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.impl;

import com.google.common.collect.ImmutableMap;
import org.onap.osam.job.Job;
import org.onap.osam.job.JobAdapter;
import org.onap.osam.job.JobType;
import org.onap.osam.model.JobBulk;
import org.onap.osam.model.JobModel;
import org.springframework.stereotype.Component;

import javax.ws.rs.BadRequestException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Component
public class JobAdapterImpl implements JobAdapter {

    @Override
    public JobModel toModel(Job job) {
        JobModel jobModel = new JobModel();
        jobModel.setUuid(job.getUuid());
        jobModel.setStatus(job.getStatus());
        jobModel.setTemplateId(job.getTemplateId());
        return jobModel;
    }

    @Override
    public JobBulk toModelBulk(List<Job> jobList) {
        return new JobBulk(jobList.stream().map(this::toModel).collect(Collectors.toList()));
    }

    @Override
    public Job createJob(JobType jobType, AsyncJobRequest request, UUID templateId, String userId, Integer indexInBulk){
        JobDaoImpl job = new JobDaoImpl();
        job.setStatus(Job.JobStatus.PENDING);
        job.setTypeAndData(jobType, ImmutableMap.of(
                "request", request,
                "userId", userId));
        job.setTemplateId(templateId);
        job.setIndexInBulk(indexInBulk);
        job.setUserId(userId);
        return job;
    }

    @Override
    public List<Job> createBulkOfJobs(Map<String, Object> bulkRequest) {
        int count;
        JobType jobType;

        try {
            count = (Integer) bulkRequest.get("count");
            jobType = JobType.valueOf((String) bulkRequest.get("type"));
        } catch (Exception exception) {
            throw new BadRequestException(exception);
        }
        List<Job> jobList = new ArrayList<>(count + 1);
        UUID templateId = UUID.randomUUID();
        for (int i = 0; i < count; i++) {
            Job child = new JobDaoImpl();
            child.setTypeAndData(jobType, bulkRequest);
            child.setStatus(Job.JobStatus.PENDING);
            child.setTemplateId(templateId);
            child.setIndexInBulk(i);
            jobList.add(child);
        }
        return jobList;
    }

}
