/*
* 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 org.apache.directory.scim.client.rest;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Response;

import org.apache.directory.scim.spec.protocol.Constants;
import org.apache.directory.scim.spec.protocol.SelfResource;
import org.apache.directory.scim.spec.filter.attribute.AttributeReferenceListWrapper;
import org.apache.directory.scim.spec.protocol.data.PatchRequest;
import org.apache.directory.scim.spec.protocol.exception.ScimException;
import org.apache.directory.scim.spec.resources.ScimUser;

// purposefully does not extend BaseScimClient, has a different utility than other clients

public class ScimSelfClient implements AutoCloseable {

  private Client client;
  private WebTarget target;
  private SelfResourceClient selfResourceClient;
  private RestCall invoke = Invocation::invoke;

  public ScimSelfClient(Client client, String baseUrl) {
    this.client = client;
    this.target = this.client.target(baseUrl).path(SelfResource.PATH);
    this.selfResourceClient = new SelfResourceClient();
  }

  public ScimSelfClient(Client client, String baseUrl, RestCall invoke) {
    this(client, baseUrl);

    this.invoke = invoke;
  }

  public ScimUser getSelf(AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
    ScimUser self;
    Response response = this.selfResourceClient.getSelf(attributes, excludedAttributes);
    self = BaseScimClient.handleResponse(response, ScimUser.class, response::readEntity);

    return self;
  }

  public ScimUser getSelf() throws ScimException {
    ScimUser self = this.getSelf(null, null);

    return self;
  }

  public void updateSelf(ScimUser scimUser, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
    Response response = this.selfResourceClient.update(scimUser, attributes, excludedAttributes);

    BaseScimClient.handleResponse(response);
  }

  public void updateSelf(ScimUser scimUser) throws ScimException {
    this.updateSelf(scimUser, null, null);
  }

  public void patchSelf(PatchRequest patchRequest, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
    Response response = this.selfResourceClient.patch(patchRequest, attributes, excludedAttributes);

    BaseScimClient.handleResponse(response);
  }

  public void patchSelf(PatchRequest patchRequest) throws ScimException {
    this.patchSelf(patchRequest, null, null);
  }

  public void deleteSelf() throws ScimException {
    Response response = this.selfResourceClient.delete();

    BaseScimClient.handleResponse(response);
  }

  public RestCall getInvoke() {
    return this.invoke;
  }

  public void setInvoke(RestCall invoke) {
    this.invoke = invoke;
  }

  @Override
  public void close() throws Exception {
    this.client.close();
  }

  private class SelfResourceClient implements SelfResource {

    @Override
    public Response getSelf(AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
      Response response;
      Invocation request = ScimSelfClient.this.target
          .queryParam(BaseScimClient.ATTRIBUTES_QUERY_PARAM, attributes)
          .queryParam(BaseScimClient.EXCLUDED_ATTRIBUTES_QUERY_PARAM, excludedAttributes)
          .request(Constants.SCIM_CONTENT_TYPE)
          .buildGet();

      try {
        response = ScimSelfClient.this.invoke.apply(request);
      } catch (RestException restException) {
        throw BaseScimClient.toScimException(restException);
      }
      return response;
    }

    @Override
    public Response update(ScimUser scimUser, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
      Response response;
      Invocation request = ScimSelfClient.this.target
          .queryParam(BaseScimClient.ATTRIBUTES_QUERY_PARAM, attributes)
          .queryParam(BaseScimClient.EXCLUDED_ATTRIBUTES_QUERY_PARAM, excludedAttributes)
          .request(Constants.SCIM_CONTENT_TYPE)
          .buildPut(Entity.entity(scimUser, Constants.SCIM_CONTENT_TYPE));

      try {
        response = ScimSelfClient.this.invoke.apply(request);
      } catch (RestException restException) {
        throw BaseScimClient.toScimException(restException);
      }
      return response;
    }

    @Override
    public Response patch(PatchRequest patchRequest, AttributeReferenceListWrapper attributes, AttributeReferenceListWrapper excludedAttributes) throws ScimException {
      Response response;
      Invocation request = ScimSelfClient.this.target
          .queryParam(BaseScimClient.ATTRIBUTES_QUERY_PARAM, attributes)
          .queryParam(BaseScimClient.EXCLUDED_ATTRIBUTES_QUERY_PARAM, excludedAttributes)
          .request(Constants.SCIM_CONTENT_TYPE)
          .build(Constants.PATCH, Entity.entity(patchRequest, Constants.SCIM_CONTENT_TYPE));

      try {
        response = ScimSelfClient.this.invoke.apply(request);
      } catch (RestException restException) {
        throw BaseScimClient.toScimException(restException);
      }
      return response;
    }

    @Override
    public Response delete() throws ScimException {
      Response response;
      Invocation request = ScimSelfClient.this.target
          .request(Constants.SCIM_CONTENT_TYPE)
          .buildDelete();

      try {
        response = ScimSelfClient.this.invoke.apply(request);
      } catch (RestException restException) {
        throw BaseScimClient.toScimException(restException);
      }
      return response;
    }
  }
}
