// 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.cloud.vm;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Table;

import com.cloud.utils.time.InaccurateClock;
import com.cloud.vm.VirtualMachine.State;

@Entity
@Table(name="op_it_work")
public class ItWorkVO {
    enum ResourceType {
        Volume,
        Nic,
        Host
    }
    
    enum Step {
        Prepare,
        Starting,
        Started,
        Release,
        Done,
        Migrating
    }
    
    @Id
    @Column(name="id")
    String id;
    
    @Column(name="created_at")
    long createdAt;
    
    @Column(name="mgmt_server_id")
    long managementServerId;
    
    @Column(name="type")
    State type;
    
    @Column(name="thread")
    String threadName;
    
    @Column(name="step")
    Step step;
    
    @Column(name="updated_at")
    long updatedAt;
    
    @Column(name="instance_id")
    long instanceId;
    
    public long getInstanceId() {
        return instanceId;
    }

    @Column(name="resource_id")
    long resourceId;
    
    @Column(name="resource_type")
    ResourceType resourceType;
    
    @Column(name="vm_type")
    @Enumerated(value=EnumType.STRING)
    VirtualMachine.Type vmType;
    
    public VirtualMachine.Type getVmType() {
        return vmType;
    }
    
    public long getResourceId() {
        return resourceId;
    }

    public void setResourceId(long resourceId) {
        this.resourceId = resourceId;
    }

    public ResourceType getResourceType() {
        return resourceType;
    }

    public void setResourceType(ResourceType resourceType) {
        this.resourceType = resourceType;
    }

    protected ItWorkVO() {
    }
    
    protected ItWorkVO(String id, long managementServerId, State type, VirtualMachine.Type vmType, long instanceId) {
        this.id = id;
        this.managementServerId = managementServerId;
        this.type = type;
        this.threadName = Thread.currentThread().getName();
        this.step = Step.Prepare;
        this.instanceId = instanceId;
        this.resourceType = null;
        this.createdAt = InaccurateClock.getTimeInSeconds();
        this.updatedAt = createdAt;
        this.vmType = vmType;
    }

    public String getId() {
        return id;
    }

    public Long getCreatedAt() {
        return createdAt;
    }
    
    public long getManagementServerId() {
        return managementServerId;
    }
    
    public void setManagementServerId(long managementServerId) {
        this.managementServerId = managementServerId;
    }
    
    public State getType() {
        return type;
    }
    
    public void setType(State type) {
        this.type = type;
    }
    
    public String getThreadName() {
        return threadName;
    }
    
    public Step getStep() {
        return step;
    }
    
    public void setStep(Step step) {
        this.step = step;
    }
    
    public long getUpdatedAt() {
        return updatedAt;
    }
    
    public void setUpdatedAt(long updatedAt) {
        this.updatedAt = updatedAt;
    }
    
    public long getSecondsTaskIsInactive() {
        return InaccurateClock.getTimeInSeconds() - this.updatedAt;
    }
    
    public long getSecondsTaskHasBeenCreated() {
        return InaccurateClock.getTimeInSeconds() - this.createdAt;
    }
    
    @Override
    public String toString() {
        return new StringBuilder("ItWork[").append(id).append("-").append(type.toString()).append("-").append(instanceId).append("-").append(step.toString()).append("]").toString();
    }
}
