package org.wso2.carbon.device.mgt.ios.services;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.ios.dep.beans.DEPDeviceUser;
import org.wso2.carbon.device.mgt.ios.dep.beans.DeviceProfile;
import org.wso2.carbon.device.mgt.ios.dep.beans.ProfileWithDevices;
import org.wso2.carbon.device.mgt.ios.util.IOSConstants;

import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;

/**
 * iOS COPE device enrollment REST-API implementation Interface.
 */
@SwaggerDefinition(
        info = @Info(
                version = "1.0.0",
                title = "",
                extensions = {
                        @Extension(properties = {
                                @ExtensionProperty(name = "name", value = "iOS DEP"),
                                @ExtensionProperty(name = "context", value = "/api/device-mgt/ios/v1.0/dep"),
                        })
                }
        ),
        tags = {
                @Tag(name = "ios,device_management", description = "iOS COPE device enrollment REST-API")
        }
)
@Scopes(scopes = {
        @Scope(
                name = "iOS operation update",
                description = "",
                key = "perm:ios:dep-view",
                permissions = {"/device-mgt/devices/dep/view"}
        ),
        @Scope(
                name = "iOS operation update",
                description = "",
                key = "perm:ios:dep-add",
                permissions = {"/device-mgt/devices/dep/add"}
        )
    }
)
@Api(value = "iOS DEP",
        description = "This carries all the resources related to the iOS Device management administrator " +
                "functionality.")
@Path("/dep")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface DEPService {

    @GET
    @Path("/account-details")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get DEP account details.",
            notes = "Get the DEP account details the server is linked.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response getAccountDetails();

    @GET
    @Path("/devices")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get DEP device details.",
            notes = "Get the DEP device details.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response getDevices(
            @ApiParam(
                    name = "limit",
                    value = "The maximum number of devices to return such as 100, 200.")
            @Size(max = 1000)
            @QueryParam("limit")
                    int limit,
            @ApiParam(
                    name = "offset",
                    value = "Starting index or the row")
            @Size(max = 1000)
            @QueryParam("offset") int offset,
            @ApiParam(
                    name = "serial",
                    value = "The serial of the device.",
                    required = false)
            @QueryParam("serial")
                    String serial,
            @ApiParam(
                    name = "model",
                    value = "The model of the device.",
                    required = false)
            @QueryParam("model")
                    String model,
            @ApiParam(
                    name = "status",
                    value = "The status of the device.",
                    required = false)
            @QueryParam("status")
                    String status,
            @ApiParam(
                    name = "requireLogin",
                    value = "require to login",
                    required = false)
            @QueryParam("requireLogin")
                    String requireLogin,
            @ApiParam(
                    name = "requireAgent",
                    value = "require to agent",
                    required = false)
            @QueryParam("requireAgent")
                    String requireAgent);

    @GET
    @Path("/devices/sync")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get DEP account details.",
            notes = "Sync the device details.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response syncDevices(
            @ApiParam(
                    name = "limit",
                    value = "The maximum number of devices to return such as 100, 200.",
                    required = true)
            @Size(max = 1000)
            @QueryParam("limit")
                    int limit,
            @ApiParam(
                    name = "cursor",
                    value = "A hex string that represents the starting position for a request. " +
                            "This is used for retrieving the list of devices that have been added" +
                            " or removed since a previous request such as 1ac73329f75815.",
                    required = true)
            @QueryParam("cursor") String cursor);

    @GET
    @Path("/devices/{deviceSerial}")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get DEP device.",
            notes = "Get the DEP device details.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response getDevice(
            @ApiParam(
                    name = "deviceSerial",
                    value = "Strings containing device serial number such as B7CJ500QF1MA.",
                    required = true)
            @PathParam("deviceSerial")
                    String deviceSerial);

    @POST
    @Path("/devices/profile")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Create a DEP profile.",
            notes = "Create a new DEP profile in Apple backend.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response createProfile(
            @ApiParam(
                    name = "deviceProfile",
                    value = "JSON object containing the details required create Apple DEP profile",
                    required = true)
                    DeviceProfile deviceProfile);

    @PUT
    @Path("/devices/profile/{profileId}")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "PUT",
            value = "Update a DEP profile.",
            notes = "Update new DEP profile in Apple backend.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response updateProfile(
            @ApiParam(
                    name = "deviceProfile",
                    value = "JSON object containing the details required create Apple DEP profile",
                    required = true)
                    DeviceProfile deviceProfile,
            @ApiParam(
                    name = "profileId",
                    value = "Profile UUID of the profile to be modified",
                    required = true)
            @PathParam("profileId") String profileId);

    @POST
    @Path("/devices/assign-profile")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Assign DEP profile to device.",
            notes = "Assign DEP devices to a profile.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response assignProfile(
            @ApiParam(
                    name = "profileWithDevices",
                    value = "JSON object containing the details required to assign " +
                            "profile to devices.",
                    required = true)
                    ProfileWithDevices profileWithDevices);

    @GET
    @Path("/profile/{profileId}")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get a profile.",
            notes = "Get the DEP profile details.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response getProfile(
            @ApiParam(
                    name = "profileId",
                    value = "String containing the ID of the profile to be retrieved.",
                    required = true)
            @PathParam("profileId")
                    String profileId);

    @GET
    @Path("/profiles")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Get DEP profiles details.",
            notes = "Get the DEP profile details.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-view")
                    })
            }
    )
    Response getProfiles(
            @ApiParam(
                    name = "offset",
                    value = "Starting offset",
                    required = true)
            @QueryParam("offset") int offset,
            @ApiParam(
                    name = "limit",
                    value = "The maximum number of devices to return such as 100, 200.",
                    required = true)
            @Size(max = 1000)
            @QueryParam("limit") int limit,
            @ApiParam(
                    name = "name",
                    value = "The name of the profile.",
                    required = false)
            @QueryParam("name")
                    String name,
            @ApiParam(
                    name = "department",
                    value = "The department of the profile.",
                    required = false)
            @QueryParam("department")
                    String department,
            @ApiParam(
                    name = "mandatory",
                    value = "Ability to skip the enrollment.",
                    required = false)
            @QueryParam("mandatory")
                    String mandatory,
            @ApiParam(
                    name = "removable",
                    value = "Ability to remove enrollment.",
                    required = false)
            @QueryParam("removable")
                    String removable);

    @POST
    @Path("/devices/remove-profile")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Remove DEP profile from device.",
            notes = "remove a DEP profile from device.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response removeProfile(
            @ApiParam(
                    name = "deviceSerialNumbers",
                    value = "List of device serials on which the Apple DEP profile " +
                            "needs to be removed.",
                    required = true)
                    List<String> deviceSerialNumbers);

    @POST
    @Path("/devices/disown/")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Disown a DEP device.",
            notes = "Warning: Remove a device fully from a DEP account. This will remove the ability to reenroll a " +
                    "device.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response disownDevices(
            @ApiParam(
                    name = "deviceSerialNumbers",
                    value = "List of device serial numbers which needs needs to be disowned " +
                            "from the Apple DEP portal.",
                    required = true)
                    List<String> deviceSerialNumbers);

    @POST
    @Path("/devices/assign-user")
    @ApiOperation(
            consumes = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Assign user.",
            notes = "Assign a device to a user.",
            tags = "IOS DEP",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:dep-add")
                    })
            }
    )
    Response assignUser(@ApiParam(
            name = "deviceUser",
            value = "JSON object containing the user and the owning devices.",
            required = true) DEPDeviceUser deviceUser);
}
