/*
 * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com).
 *
 * WSO2 LLC. 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 org.wso2.carbon.identity.api.server.consent.management.v2;

import org.wso2.carbon.identity.api.server.consent.management.v2.factories.ConsentsApiServiceFactory;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentCreateRequest;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentDTO;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentListResponse;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentResponseDTO;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentUpdateRequest;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ConsentValidateResponse;
import org.wso2.carbon.identity.api.server.consent.management.v2.model.ErrorDTO;

import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import io.swagger.annotations.*;

import javax.validation.constraints.*;

@Path("/consents")
@Api(description = "The consents API")

public class ConsentsApi  {

    private final ConsentsApiService delegate;

    public ConsentsApi() {

        this.delegate = ConsentsApiServiceFactory.getConsentsApi();
    }

    @Valid
    @POST
    
    @Consumes({ "application/json" })
    @Produces({ "application/json" })
    @ApiOperation(value = "Create a consent record", notes = "Record a consent on behalf of a subject user.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_create` ", response = ConsentResponseDTO.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents", })
    @ApiResponses(value = { 
        @ApiResponse(code = 201, message = "Consent recorded successfully", response = ConsentResponseDTO.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 403, message = "Forbidden", response = ErrorDTO.class),
        @ApiResponse(code = 409, message = "Conflict", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsCreate(@ApiParam(value = "" ,required=true) @Valid ConsentCreateRequest consentCreateRequest) {

        return delegate.consentsCreate(consentCreateRequest );
    }

    @Valid
    @GET
    @Path("/{consentId}")
    
    @Produces({ "application/json" })
    @ApiOperation(value = "Get a consent record", notes = "Retrieve a specific consent record by consent ID.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_view` ", response = ConsentDTO.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "Consent record details", response = ConsentDTO.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 403, message = "Forbidden", response = ErrorDTO.class),
        @ApiResponse(code = 404, message = "Not Found", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsGet( @Size(min=1,max=255)@ApiParam(value = "ID of the consent.",required=true) @PathParam("consentId") String consentId) {

        return delegate.consentsGet(consentId );
    }

    @Valid
    @GET
    
    
    @Produces({ "application/json" })
    @ApiOperation(value = "List consent records", notes = "Retrieve consent records with optional filtering.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_view` ", response = ConsentListResponse.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "List of consents", response = ConsentListResponse.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsList(    @Valid @Size(max=255)@ApiParam(value = "Username whose consents are retrieved. Involvement is set by `relation`. Requires `relation`.")  @QueryParam("userId") String userId,     @Valid@ApiParam(value = "Relation of `userId` to the retrieved consents. SUBJECT returns consents given by the user, AUTHORIZER returns consents the user is listed as an authorizer of, ANY returns both. Requires `userId`. ", allowableValues="SUBJECT, AUTHORIZER, ANY")  @QueryParam("relation") String relation,     @Valid @Size(max=255)@ApiParam(value = "Filter by service ID.")  @QueryParam("serviceId") String serviceId,     @Valid@ApiParam(value = "Filter consents by state.", allowableValues="PENDING, ACTIVE, REJECTED, REVOKED, EXPIRED")  @QueryParam("state") String state,     @Valid@ApiParam(value = "Filter consents by purpose ID.")  @QueryParam("purposeId") String purposeId,     @Valid@ApiParam(value = "Filter consents by specific purpose version ID.")  @QueryParam("purposeVersionId") String purposeVersionId,     @Valid@ApiParam(value = "Filter consents by custom properties using dot notation `properties.<key>`, and by `timestamp` (milliseconds since epoch). Properties support 'sw' (starts with), 'co' (contains), 'ew' (ends with), and 'eq' (equals) operations. `timestamp` supports 'ge' (greater than or equals) and 'le' (less than or equals) operations. Combine multiple conditions with the 'and' logical operator. Examples: - filter=properties.dataCategory eq personal - filter=properties.region eq EU and properties.dataCategory eq personal - filter=timestamp ge 1744000000000 and timestamp le 1766383796000 ")  @QueryParam("filter") String filter,     @Valid@ApiParam(value = "Specifies the required attributes in the response as a comma-separated string. Supported values: `purposes`, `authorizations`, `properties`. Example: attributes=purposes,properties ")  @QueryParam("attributes") String attributes,     @Valid @Min(1)@ApiParam(value = "Maximum number of records to return.", defaultValue="10") @DefaultValue("10")  @QueryParam("limit") Integer limit,     @Valid@ApiParam(value = "Cursor for forward pagination. Pass the base64-encoded UUID of the last item received from the previous page to retrieve the next page of results. ")  @QueryParam("after") String after,     @Valid@ApiParam(value = "Cursor for backward pagination. Pass the base64-encoded UUID of the first item received from the current page to retrieve the previous page of results. ")  @QueryParam("before") String before) {

        return delegate.consentsList(userId,  relation,  serviceId,  state,  purposeId,  purposeVersionId,  filter,  attributes,  limit,  after,  before );
    }

    @Valid
    @POST
    @Path("/{consentId}/revoke")
    
    @Produces({ "application/json" })
    @ApiOperation(value = "Revoke a consent", notes = "Revokes the consent. Idempotent — if the consent is already revoked, returns 204 with no error.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_update` ", response = Void.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents", })
    @ApiResponses(value = { 
        @ApiResponse(code = 204, message = "Consent revoked successfully", response = Void.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 403, message = "Forbidden", response = ErrorDTO.class),
        @ApiResponse(code = 404, message = "Not Found", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsRevoke( @Size(min=1,max=255)@ApiParam(value = "ID of the consent.",required=true) @PathParam("consentId") String consentId) {

        return delegate.consentsRevoke(consentId );
    }

    @Valid
    @PATCH
    @Path("/{consentId}")
    @Consumes({ "application/json" })
    @Produces({ "application/json" })
    @ApiOperation(value = "Update a consent record", notes = "Update an existing consent record's expiry time, properties, and authorizations. All fields in the request body are optional; omit a field to leave that aspect of the consent unchanged. `expiryTime` sets or clears the expiry, `properties` replaces the full property map, and `authorizations` upserts the listed users — adding them as authorizers if absent or overriding their state if present.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_update` ", response = ConsentDTO.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "Consent updated successfully", response = ConsentDTO.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 403, message = "Forbidden", response = ErrorDTO.class),
        @ApiResponse(code = 404, message = "Not Found", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsUpdate( @Size(min=1,max=255)@ApiParam(value = "ID of the consent.",required=true) @PathParam("consentId") String consentId, @ApiParam(value = "" ,required=true) @Valid ConsentUpdateRequest consentUpdateRequest) {

        return delegate.consentsUpdate(consentId,  consentUpdateRequest );
    }

    @Valid
    @GET
    @Path("/{consentId}/validate")
    
    @Produces({ "application/json" })
    @ApiOperation(value = "Get the current state of a consent object", notes = "Returns the current state of a consent record, performing a lazy expiry check.<br> <b>Scope(Permission) required:</b> `internal_consent_mgt_consent_view` ", response = ConsentValidateResponse.class, authorizations = {
        @Authorization(value = "BasicAuth"),
        @Authorization(value = "OAuth2", scopes = {
            
        })
    }, tags={ "Consents" })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "Validation result", response = ConsentValidateResponse.class),
        @ApiResponse(code = 400, message = "Bad Request", response = ErrorDTO.class),
        @ApiResponse(code = 401, message = "Unauthorized", response = ErrorDTO.class),
        @ApiResponse(code = 403, message = "Forbidden", response = ErrorDTO.class),
        @ApiResponse(code = 404, message = "Not Found", response = ErrorDTO.class),
        @ApiResponse(code = 500, message = "Server Error", response = ErrorDTO.class)
    })
    public Response consentsValidate( @Size(min=1,max=255)@ApiParam(value = "ID of the consent.",required=true) @PathParam("consentId") String consentId) {

        return delegate.consentsValidate(consentId );
    }

}
