/*
Copyright (c) 2015 Red Hat, Inc.
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.
*/

package org.ovirt.engine.sdk4.services;

import java.io.IOException;
import org.ovirt.engine.sdk4.Request;
import org.ovirt.engine.sdk4.Response;
import org.ovirt.engine.sdk4.Service;
import org.ovirt.engine.sdk4.builders.DiskBuilder;
import org.ovirt.engine.sdk4.builders.HostBuilder;
import org.ovirt.engine.sdk4.builders.StorageDomainBuilder;
import org.ovirt.engine.sdk4.types.Disk;
import org.ovirt.engine.sdk4.types.Host;
import org.ovirt.engine.sdk4.types.StorageDomain;

/**
 * Manages a single disk.
 */
public interface DiskService extends MeasurableService {
    /**
     * This operation copies a disk to the specified storage domain.
     * 
     * For example, copy of a disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/copy
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     *   <disk>
     *     <name>mydisk</name>
     *   </disk>
     * </action>
     * ----
     */
    public interface CopyRequest extends Request<CopyRequest, CopyResponse> {
        /**
         * Indicates if the copy should be performed asynchronously.
         */
        CopyRequest async(Boolean async);
        CopyRequest disk(Disk disk);
        CopyRequest disk(DiskBuilder disk);
        /**
         * Indicates if the results should be filtered according to the permissions of the user.
         */
        CopyRequest filter(Boolean filter);
        CopyRequest storageDomain(StorageDomain storageDomain);
        /**
         * The storage domain where the new disk will be created. Can be specified using the `id` or `name`
         * attributes. For example, to copy a disk to the storage domain named `mydata` send a request like this:
         * 
         * ....
         * POST /ovirt-engine/api/storagedomains/123/disks/789
         * ....
         * 
         * With a request body like this:
         * 
         * [source,xml]
         * ----
         * <action>
         *   <storage_domain>
         *     <name>mydata</name>
         *   </storage_domain>
         * </action>
         * ----
         */
        CopyRequest storageDomain(StorageDomainBuilder storageDomain);
    }
    
    /**
     * This operation copies a disk to the specified storage domain.
     * 
     * For example, copy of a disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/copy
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     *   <disk>
     *     <name>mydisk</name>
     *   </disk>
     * </action>
     * ----
     */
    public interface CopyResponse extends Response {
    }
    
    /**
     * This operation copies a disk to the specified storage domain.
     * 
     * For example, copy of a disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/copy
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     *   <disk>
     *     <name>mydisk</name>
     *   </disk>
     * </action>
     * ----
     */
    CopyRequest copy();
    
    /**
     * Exports a disk to an export storage domain.
     */
    public interface ExportRequest extends Request<ExportRequest, ExportResponse> {
        /**
         * Indicates if the export should be performed asynchronously.
         */
        ExportRequest async(Boolean async);
        /**
         * Indicates if the results should be filtered according to the permissions of the user.
         */
        ExportRequest filter(Boolean filter);
        ExportRequest storageDomain(StorageDomain storageDomain);
        ExportRequest storageDomain(StorageDomainBuilder storageDomain);
    }
    
    /**
     * Exports a disk to an export storage domain.
     */
    public interface ExportResponse extends Response {
    }
    
    /**
     * Exports a disk to an export storage domain.
     */
    ExportRequest export();
    
    /**
     * Retrieves the description of the disk.
     */
    public interface GetRequest extends Request<GetRequest, GetResponse> {
    }
    
    /**
     * Retrieves the description of the disk.
     */
    public interface GetResponse extends Response {
        /**
         * The description of the disk.
         */
        Disk disk();
    }
    
    /**
     * Retrieves the description of the disk.
     */
    GetRequest get();
    
    /**
     * Moves a disk to another storage domain.
     * 
     * For example, to move the disk with identifier `123` to a storage domain with identifier `456` send the following
     * request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/move
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     * </action>
     * ----
     */
    public interface MoveRequest extends Request<MoveRequest, MoveResponse> {
        /**
         * Indicates if the move should be performed asynchronously.
         */
        MoveRequest async(Boolean async);
        /**
         * Indicates if the results should be filtered according to the permissions of the user.
         */
        MoveRequest filter(Boolean filter);
        MoveRequest storageDomain(StorageDomain storageDomain);
        MoveRequest storageDomain(StorageDomainBuilder storageDomain);
    }
    
    /**
     * Moves a disk to another storage domain.
     * 
     * For example, to move the disk with identifier `123` to a storage domain with identifier `456` send the following
     * request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/move
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     * </action>
     * ----
     */
    public interface MoveResponse extends Response {
    }
    
    /**
     * Moves a disk to another storage domain.
     * 
     * For example, to move the disk with identifier `123` to a storage domain with identifier `456` send the following
     * request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/move
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <storage_domain id="456"/>
     * </action>
     * ----
     */
    MoveRequest move();
    
    /**
     * Refreshes a direct LUN disk with up-to-date information from the storage.
     * 
     * Refreshing a direct LUN disk is useful when:
     * 
     * - The LUN was added using the API without the host parameter, and therefore does not contain
     *   any information from the storage (see <<services/disks/methods/add, DisksService::add>>).
     * - New information about the LUN is available on the storage and you want to update the LUN with it.
     * 
     * To refresh direct LUN disk `123` using host `456`, send the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/refreshlun
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <host id='456'/>
     * </action>
     * ----
     */
    public interface RefreshLunRequest extends Request<RefreshLunRequest, RefreshLunResponse> {
        RefreshLunRequest host(Host host);
        /**
         * The host that will be used to refresh the direct LUN disk.
         */
        RefreshLunRequest host(HostBuilder host);
    }
    
    /**
     * Refreshes a direct LUN disk with up-to-date information from the storage.
     * 
     * Refreshing a direct LUN disk is useful when:
     * 
     * - The LUN was added using the API without the host parameter, and therefore does not contain
     *   any information from the storage (see <<services/disks/methods/add, DisksService::add>>).
     * - New information about the LUN is available on the storage and you want to update the LUN with it.
     * 
     * To refresh direct LUN disk `123` using host `456`, send the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/refreshlun
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <host id='456'/>
     * </action>
     * ----
     */
    public interface RefreshLunResponse extends Response {
    }
    
    /**
     * Refreshes a direct LUN disk with up-to-date information from the storage.
     * 
     * Refreshing a direct LUN disk is useful when:
     * 
     * - The LUN was added using the API without the host parameter, and therefore does not contain
     *   any information from the storage (see <<services/disks/methods/add, DisksService::add>>).
     * - New information about the LUN is available on the storage and you want to update the LUN with it.
     * 
     * To refresh direct LUN disk `123` using host `456`, send the following request:
     * 
     * [source]
     * ----
     * POST /ovirt-engine/api/disks/123/refreshlun
     * ----
     * 
     * With the following request body:
     * 
     * [source,xml]
     * ----
     * <action>
     *   <host id='456'/>
     * </action>
     * ----
     */
    RefreshLunRequest refreshLun();
    
    /**
     * Removes a disk.
     */
    public interface RemoveRequest extends Request<RemoveRequest, RemoveResponse> {
        /**
         * Indicates if the remove should be performed asynchronously.
         */
        RemoveRequest async(Boolean async);
    }
    
    /**
     * Removes a disk.
     */
    public interface RemoveResponse extends Response {
    }
    
    /**
     * Removes a disk.
     */
    RemoveRequest remove();
    
    /**
     * Sparsify the disk.
     * 
     * Sparsification frees space in the disk image that is not used by its
     * filesystem. As a result, the image will occupy less space on the storage.
     * 
     * Currently sparsification works only on disks without snapshots. Disks
     * having derived disks are also not allowed.
     */
    public interface SparsifyRequest extends Request<SparsifyRequest, SparsifyResponse> {
    }
    
    /**
     * Sparsify the disk.
     * 
     * Sparsification frees space in the disk image that is not used by its
     * filesystem. As a result, the image will occupy less space on the storage.
     * 
     * Currently sparsification works only on disks without snapshots. Disks
     * having derived disks are also not allowed.
     */
    public interface SparsifyResponse extends Response {
    }
    
    /**
     * Sparsify the disk.
     * 
     * Sparsification frees space in the disk image that is not used by its
     * filesystem. As a result, the image will occupy less space on the storage.
     * 
     * Currently sparsification works only on disks without snapshots. Disks
     * having derived disks are also not allowed.
     */
    SparsifyRequest sparsify();
    
    /**
     * This operation updates the disk with the appropriate parameters.
     * The only field that can be updated is `qcow_version`.
     * 
     * For example, update disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * PUT /ovirt-engine/api/disks/123
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <disk>
     *   <qcow_version>qcow2_v3</qcow_version>
     * </disk>
     * ----
     * 
     * Since the backend operation is asynchronous the disk element which will be returned
     * to the user might not be synced with the changed properties.
     */
    public interface UpdateRequest extends Request<UpdateRequest, UpdateResponse> {
        UpdateRequest disk(Disk disk);
        /**
         * The update to apply to the disk.
         */
        UpdateRequest disk(DiskBuilder disk);
    }
    
    /**
     * This operation updates the disk with the appropriate parameters.
     * The only field that can be updated is `qcow_version`.
     * 
     * For example, update disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * PUT /ovirt-engine/api/disks/123
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <disk>
     *   <qcow_version>qcow2_v3</qcow_version>
     * </disk>
     * ----
     * 
     * Since the backend operation is asynchronous the disk element which will be returned
     * to the user might not be synced with the changed properties.
     */
    public interface UpdateResponse extends Response {
        /**
         * The update to apply to the disk.
         */
        Disk disk();
    }
    
    /**
     * This operation updates the disk with the appropriate parameters.
     * The only field that can be updated is `qcow_version`.
     * 
     * For example, update disk can be facilitated using the following request:
     * 
     * [source]
     * ----
     * PUT /ovirt-engine/api/disks/123
     * ----
     * 
     * With a request body like this:
     * 
     * [source,xml]
     * ----
     * <disk>
     *   <qcow_version>qcow2_v3</qcow_version>
     * </disk>
     * ----
     * 
     * Since the backend operation is asynchronous the disk element which will be returned
     * to the user might not be synced with the changed properties.
     */
    UpdateRequest update();
    
    /**
     * Reference to the service that manages the permissions assigned to the disk.
     */
    AssignedPermissionsService permissionsService();
    /**
     * Service locator method, returns individual service on which the URI is dispatched.
     */
    Service service(String path);
}

