// 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.storage;

import java.util.Date;
import java.util.UUID;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDaoBase;

@Entity
@Table(name = "upload")
public class UploadVO implements Upload {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    long id;

    @Column(name = "uuid")
    private String uuid;

    @Column(name = "host_id")
    private long dataStoreId;

    @Column(name = "type_id")
    private long typeId;

    @Column(name = GenericDaoBase.CREATED_COLUMN)
    private Date created = null;

    @Column(name = "last_updated")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date lastUpdated = null;

    @Column(name = "upload_pct")
    private int uploadPercent;

    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    private Type type;

    @Column(name = "mode")
    @Enumerated(EnumType.STRING)
    private Mode mode = Mode.FTP_UPLOAD;

    @Column(name = "upload_state")
    @Enumerated(EnumType.STRING)
    private Status uploadState;

    @Column(name = "error_str")
    private String errorString;

    @Column(name = "job_id")
    private String jobId;

    @Column(name = "url")
    private String uploadUrl;

    @Column(name = "install_path")
    private String installPath;

    @Override
    public long getDataStoreId() {
        return dataStoreId;
    }

    public void setDataStoreId(long hostId) {
        this.dataStoreId = hostId;
    }

    @Override
    public long getId() {
        return id;
    }

    @Override
    public String getUuid() {
        return uuid;
    }

    @Override
    public Date getCreated() {
        return created;
    }

    @Override
    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date date) {
        lastUpdated = date;
    }

    public UploadVO(long hostId, long templateId) {
        super();
        this.dataStoreId = hostId;
        this.typeId = templateId;
        this.uuid = UUID.randomUUID().toString();
    }

    public UploadVO(long hostId, long typeId, Date lastUpdated, Status uploadState, Type type, String uploadUrl,
            Mode mode) {
        super();
        this.dataStoreId = hostId;
        this.typeId = typeId;
        this.lastUpdated = lastUpdated;
        this.uploadState = uploadState;
        this.mode = mode;
        this.type = type;
        this.uploadUrl = uploadUrl;
        this.uuid = UUID.randomUUID().toString();
    }

    public UploadVO(long hostId, long typeId, Date lastUpdated, Status uploadState, int uploadPercent, Type type,
            Mode mode) {
        super();
        this.dataStoreId = hostId;
        this.typeId = typeId;
        this.lastUpdated = lastUpdated;
        this.uploadState = uploadState;
        this.uploadPercent = uploadPercent;
        this.type = type;
        this.mode = mode;
        this.uuid = UUID.randomUUID().toString();

    }

    protected UploadVO() {
    }

    public UploadVO(Long uploadId) {
        this.id = uploadId;
    }

    public void setErrorString(String errorString) {
        this.errorString = errorString;
    }

    @Override
    public String getErrorString() {
        return errorString;
    }

    public void setJobId(String jobId) {
        this.jobId = jobId;
    }

    @Override
    public String getJobId() {
        return jobId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof UploadVO) {
            UploadVO other = (UploadVO) obj;
            return (this.typeId == other.getTypeId() && this.dataStoreId == other.getDataStoreId() && this.type == other
                    .getType());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return NumbersUtil.hash(id);
    }

    @Override
    public int getUploadPercent() {
        return uploadPercent;
    }

    public void setUploadPercent(int uploadPercent) {
        this.uploadPercent = uploadPercent;
    }

    @Override
    public Status getUploadState() {
        return uploadState;
    }

    public void setUploadState(Status uploadState) {
        this.uploadState = uploadState;
    }

    @Override
    public long getTypeId() {
        return typeId;
    }

    public void setTypeId(long typeId) {
        this.typeId = typeId;
    }

    @Override
    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    @Override
    public Mode getMode() {
        return mode;
    }

    public void setMode(Mode mode) {
        this.mode = mode;
    }

    @Override
    public String getUploadUrl() {
        return uploadUrl;
    }

    public void setUploadUrl(String uploadUrl) {
        this.uploadUrl = uploadUrl;
    }

    @Override
    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public String getInstallPath() {
        return installPath;
    }

    @Override
    public void setInstallPath(String installPath) {
        this.installPath = installPath;
    }
}
