/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package com.epam.dlab.dto.computational;

import com.epam.dlab.dto.ResourceURL;
import com.epam.dlab.dto.SchedulerJobDTO;
import com.epam.dlab.dto.aws.computational.ClusterConfig;
import com.epam.dlab.dto.base.DataEngineType;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserComputationalResource {
	@JsonProperty("computational_name")
	private String computationalName;
	@JsonProperty("computational_id")
	private String computationalId;
	@JsonProperty("image")
	private String imageName;
	@JsonProperty("template_name")
	private String templateName;
	@JsonProperty
	private String status;
	@JsonProperty("up_time")
	private Date uptime;
	@JsonProperty("scheduler_data")
	private SchedulerJobDTO schedulerData;
	@JsonProperty("reupload_key_required")
	private boolean reuploadKeyRequired = false;
	@JsonProperty("computational_url")
	private List<ResourceURL> resourceUrl;
	@JsonProperty("last_activity")
	private LocalDateTime lastActivity;
	@JsonProperty("master_node_shape")
	private String masterNodeShape;
	@JsonProperty("dataengine_instance_shape")
	private String dataengineShape;
	@JsonProperty("instance_id")
	private String instanceId;
	protected List<ClusterConfig> config;
	private Map<String,String> tags;

	public UserComputationalResource(String computationalName, String computationalId, String imageName,
									 String templateName, String status, Date uptime, SchedulerJobDTO schedulerData,
									 boolean reuploadKeyRequired, List<ResourceURL> resourceUrl,
									 LocalDateTime lastActivity, Map<String,String> tags) {
		this.computationalName = computationalName;
		this.computationalId = computationalId;
		this.imageName = imageName;
		this.templateName = templateName;
		this.status = status;
		this.uptime = uptime;
		this.schedulerData = schedulerData;
		this.reuploadKeyRequired = reuploadKeyRequired;
		this.resourceUrl = resourceUrl;
		this.lastActivity = lastActivity;
		this.tags = tags;
	}

	public DataEngineType getDataEngineType() {
		return DataEngineType.fromDockerImageName(imageName);
	}
}
