/*
* 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.protocol.Constants;
import org.apache.directory.scim.protocol.SelfResource;
import org.apache.directory.scim.spec.filter.attribute.AttributeReferenceListWrapper;
import org.apache.directory.scim.protocol.data.PatchRequest;
import org.apache.directory.scim.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;
    }
  }
}
