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.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.AuthorizationScope;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
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.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.ios.api.utils.beans.APNSBean;
import org.wso2.carbon.device.mgt.ios.api.utils.beans.LocationBean;
import org.wso2.carbon.device.mgt.ios.api.utils.beans.TokenBean;
import org.wso2.carbon.device.mgt.ios.util.IOSConstants;

import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
 * iOS device information REST-API implementation.
 */
@SwaggerDefinition(
        info = @Info(
                version = "1.0.0",
                title = "",
                extensions = {
                        @Extension(properties = {
                                @ExtensionProperty(name = "name", value = "iOS Device Management"),
                                @ExtensionProperty(name = "context", value = "/api/device-mgt/ios/v1.0/devices"),
                        })
                }
        ),
        tags = {
                @Tag(name = "ios,device_management", description = "")
        }
)
@Scopes(scopes = {
        @Scope(
                name = "View device info",
                description = "",
                key = "perm:ios:view-device",
                permissions = {"/device-mgt/devices/owning-device/view"}
        ),
        @Scope(
                name = "Enroll iOS device",
                description = "",
                key = "perm:ios:enroll",
                permissions = {"/device-mgt/devices/enroll/ios"}
        ),
        @Scope(
                name = "View applications",
                description = "",
                key = "perm:ios:applications",
                permissions = {"/device-mgt/devices/owning-device/operations/ios/applications"}
        )
})
@Api(value = "iOS Device Management",
     description = "This carries all the resources related to the iOS Device Information.")
@Path("/devices")
public interface DeviceManagementService {

    @GET
    @Path("/{id}")
    @ApiOperation(
            produces = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Getting the iOS Device Information",
            notes = "Get the IOS Device information via this REST API.",
            tags = "IOS Device details.",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:view-device")
                    })
            }
    )
    @ApiResponses(
            value = {
                    @ApiResponse(
                            code = 200,
                            message = "OK. \n Successfully fetched IOS device information.",
                            response = PlatformConfiguration.class,
                            responseContainer = "List",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Type",
                                            description = "The content type of the body"),
                                    @ResponseHeader(
                                            name = "ETag",
                                            description = "Entity Tag of the response resource.\n" +
                                                    "Used by caches, or in conditional requests."),
                                    @ResponseHeader(
                                            name = "Last-Modified",
                                            description = "Date and time the resource was last modified.\n" +
                                                    "Used by caches, or in conditional requests."),
                            }
                    ),
                    @ApiResponse(
                            code = 304,
                            message = "Not Modified. \n  Empty body because the client already has the latest version" +
                                    " of the requested resource."),
                    @ApiResponse(
                            code = 406,
                            message = "Not Acceptable.\n The requested media type is not supported."),
                    @ApiResponse(
                            code = 500,
                            message = "Internal Server Error. \n Server error occurred while fetching the iOS device " +
                                    "information."
                    )
            }
    )
    Response getDeviceInformation(
            @ApiParam(
                    name = "accept-header",
                    value = "Accept-Header")
            @HeaderParam("Accept") String acceptHeader,
            @ApiParam(
                    name = "id",
                    value = "The iOS Device Identifier.")
            @PathParam("id") String deviceId);

    @PUT
    @Path("/pushtoken/{id}")
    @ApiOperation(
            produces = MediaType.APPLICATION_JSON,
            httpMethod = "PUT",
            value = "Updating the APNS token.",
            notes = "This resource is used to update the APNS token.",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:enroll")
                    })
            }
    )
    @ApiResponses(
            value = {
                    @ApiResponse(
                            code = 200,
                            message = "OK. \n Successfully updated the APNS token.",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Type",
                                            description = "The content type of the body"),
                                    @ResponseHeader(
                                            name = "ETag",
                                            description = "Entity Tag of the response resource.\n" +
                                                    "Used by caches, or in conditional requests."),
                                    @ResponseHeader(
                                            name = "Last-Modified",
                                            description = "Date and time the resource was last modified.\n" +
                                                    "Used by caches, or in conditional requests.")}),
                    @ApiResponse(
                            code = 400,
                            message = "Bad Request. \n Invalid request or validation error."),
                    @ApiResponse(
                            code = 415,
                            message = "Unsupported media type. \n The format of the requested entity was not " +
                                    "supported."),
                    @ApiResponse(
                            code = 500,
                            message = "Internal Server Error. \n " +
                                    "Server error occurred while updating APNS Token."
                    )
            }
    )
    Response updateAPNSToken(
            @ApiParam(
                    name = "accept-header",
                    value = "Accept-Header")
            @HeaderParam("Accept") String acceptHeader,
            @ApiParam(
                    name = "id",
                    value = "The iOS device identifier.")
            @PathParam("id") String deviceId,

            APNSBean apnsBean);

    @PUT
    @Path("/location/{id}")
    @ApiOperation(
            produces = MediaType.APPLICATION_JSON,
            httpMethod = "PUT",
            value = "Updating the iOS device Location.",
            notes = "This resource is used to update the specific location of the iOS Device.",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:enroll")
                    })
            }
    )
    @ApiResponses(
            value = {
                    @ApiResponse(
                            code = 200,
                            message = "OK. \n Successfully updated the device Location.",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Type",
                                            description = "The content type of the body"),
                                    @ResponseHeader(
                                            name = "ETag",
                                            description = "Entity Tag of the response resource.\n" +
                                                    "Used by caches, or in conditional requests."),
                                    @ResponseHeader(
                                            name = "Last-Modified",
                                            description = "Date and time the resource was last modified.\n" +
                                                    "Used by caches, or in conditional requests.")}),
                    @ApiResponse(
                            code = 400,
                            message = "Bad Request. \n Invalid request or validation error."),
                    @ApiResponse(
                            code = 415,
                            message = "Unsupported media type. \n The format of the requested entity was not " +
                                    "supported."),
                    @ApiResponse(
                            code = 500,
                            message = "Internal Server Error. \n " +
                                    "Server error occurred while updating the iOS device location."
                    )
            }
    )
    Response updateLocation(
            @ApiParam(
                    name = "accept-header",
                    value = "Accept-Header")
            @HeaderParam("Accept") String acceptHeader,
            @ApiParam(
                    name = "id",
                    value = "The iOS device identifier.")
            @PathParam("id") String deviceId,
            LocationBean locationBean);

    @POST
    @Path("/udid")
    @ApiOperation(
            produces = MediaType.APPLICATION_JSON,
            httpMethod = "POST",
            value = "Getting the Unique Device Identifier (UDID).",
            notes = "Get the unique device identifier (UDID) of the iOS device.",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:enroll")
                    })
            }
    )
    @ApiResponses(
            value = {
                    @ApiResponse(
                            code = 200,
                            message = "OK. \n Successfully retrieved the UDID.",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Type",
                                            description = "The content type of the body"),
                                    @ResponseHeader(
                                            name = "ETag",
                                            description = "Entity Tag of the response resource.\n" +
                                                    "Used by caches, or in conditional requests."),
                                    @ResponseHeader(
                                            name = "Last-Modified",
                                            description = "Date and time the resource was last modified.\n" +
                                                    "Used by caches, or in conditional requests.")}),
                    @ApiResponse(
                            code = 304,
                            message = "Not Modified. \n " +
                                    "Empty body because the client already has the latest version of the requested " +
                                    "resource."),
                    @ApiResponse(
                            code = 400,
                            message = "Bad Request. \n Invalid request or validation error."
                    ),
                    @ApiResponse(
                            code = 404,
                            message = "Not Acceptable.\n No device/s matched the given filters."
                    ),
                    @ApiResponse(
                            code = 406,
                            message = "Not Acceptable.\n The requested media type is not supported."),
                    @ApiResponse(
                            code = 415,
                            message = "Unsupported media type. \n The format of the requested entity was not " +
                                    "supported."),
                    @ApiResponse(
                            code = 500,
                            message = "Internal Server Error. \n " +
                                    "Server error occurred while fetching Device UDID."
                    )
            })
    Response getDeviceUDID(
            @ApiParam(name = "acceptHeader",
                      value = "Accept Header")
            @HeaderParam("Accept") String acceptHeader,
            @ApiParam(name = "tokenBean",
                      value = "Token related information.")
                    TokenBean tokenBean);

    @GET
    @Path("/{id}/applications")
    @ApiOperation(
            produces = MediaType.APPLICATION_JSON,
            httpMethod = "GET",
            value = "Getting List of iOS applications",
            notes = "Get the list of applications on an iOS device..",
            tags = "IOS Device Management",
            extensions = {
                    @Extension(properties = {
                            @ExtensionProperty(name = IOSConstants.SCOPE, value = "perm:ios:applications")
                    })
            }
    )
    @ApiResponses(
            value = {
                    @ApiResponse(
                            code = 200,
                            message = "OK. \n Successfully returned the list of applications installed on the device.",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Type",
                                            description = "The content type of the body"),
                                    @ResponseHeader(
                                            name = "ETag",
                                            description = "Entity Tag of the response resource.\n" +
                                                    "Used by caches, or in conditional requests."),
                                    @ResponseHeader(
                                            name = "Last-Modified",
                                            description = "Date and time the resource was last modified \n" +
                                                    "Used by caches, or in conditional requests.")}),
                    @ApiResponse(
                            code = 303,
                            message = "See Other. \n " +
                                    "The source can be retrieved from the URL specified in the location header.\n",
                            responseHeaders = {
                                    @ResponseHeader(
                                            name = "Content-Location",
                                            description = "The Source URL of the document.")}),
                    @ApiResponse(
                            code = 304,
                            message = "Not Modified. \n " +
                                    "Empty body because the client already has the latest version of the requested " +
                                    "resource.\n"),
                    @ApiResponse(
                            code = 400,
                            message = "Bad Request. \n Invalid request or validation error."
                    ),
                    @ApiResponse(
                            code = 404,
                            message = "Not Found. \n The specified device does not exist."
                    ),
                    @ApiResponse(
                            code = 406,
                            message = "Not Acceptable. \n The requested media type is not supported."),
                    @ApiResponse(
                            code = 500,
                            message = "Internal Server Error. \n " +
                                    "Server error occurred whilst retrieving the list of installed application from " +
                                    "the device."
                    )
            })
    Response getApplicationList(
            @ApiParam(name = "deviceId",
                      value = "The iOS device ID.")
            @PathParam("id") String deviceId);
}
