/*
 * (c) 2020 Pluto Inc.
 */
package tv.pluto.grpc.partners;

import static tv.pluto.ip.dal.partner.Partners.CFeedsSyncAllIdsRequest;
import static tv.pluto.ip.dal.partner.Partners.CFeedsSyncDocumentsRequest;
import static tv.pluto.ip.dal.partner.Partners.GetByIdRequest;
import static tv.pluto.ip.dal.partner.Partners.GetByIdResponse;
import static tv.pluto.ip.dal.partner.Partners.GetByIdsRequest;
import static tv.pluto.ip.dal.partner.Partners.GetByIdsResponse;
import static tv.pluto.ip.dal.partner.Partners.GetDocumentsUpdatedBetweenDatesRequest;
import static tv.pluto.ip.dal.partner.Partners.GetItemsAllRequest;
import static tv.pluto.ip.dal.partner.Partners.GetItemsAllResponse;

import io.grpc.Channel;
import java.util.List;
import java.util.logging.Logger;
import tv.pluto.grpc.GenericGrpcClient;
import tv.pluto.ip.dal.partner.PartnerManagerGrpc;
import tv.pluto.ip.dal.partner.Partners;

/** Class represents gRPC client for <b>partners.proto</b> file */
public class PartnersClient extends GenericGrpcClient {
  private static final Logger logger = Logger.getLogger(PartnersClient.class.getName());

  private PartnerManagerGrpc.PartnerManagerBlockingStub blockingStub;

  public PartnersClient(Channel channel, boolean isAuth) {
    this.getDocumentsUpdatedBetweenDatesRequestBuilder =
        GetDocumentsUpdatedBetweenDatesRequest.newBuilder();
    this.getCFeedsAllIdsBuilder = CFeedsSyncAllIdsRequest.newBuilder();
    this.getCFeedsSyncDocumentsBuilder = CFeedsSyncDocumentsRequest.newBuilder();
    blockingStub = PartnerManagerGrpc.newBlockingStub(channel);
    blockingStub =
        isAuth
            ? blockingStub.withInterceptors(CLIENT_INTERCEPTOR_AUTH)
            : blockingStub.withInterceptors(CLIENT_INTERCEPTOR);
  }

  /**
   * Method represents gRPC method GetPartnerById from <b>partners.proto</b> file
   *
   * @param id id of the partner
   * @return GetPartnerByIdResponse object
   */
  public GetByIdResponse getPartnerById(String id) {
    logger.info("Getting info for partner with id: " + id + " ...");
    GetByIdRequest request = GetByIdRequest.newBuilder().setId(id).build();

    return blockingStub.getById(request);
  }

  /**
   * Method represents gRPC method GetPartnersByIds from <b>partners.proto</b> file
   *
   * @param partnersIds List of partners ids to search
   * @return GetPartnersByIdsResponse object
   */
  public GetByIdsResponse getPartnersByIds(List<String> partnersIds) {
    logger.info("Getting list of partners for ids: " + partnersIds + " ...");

    GetByIdsRequest request = GetByIdsRequest.newBuilder().addAllIds(partnersIds).build();

    return blockingStub.getByIds(request);
  }

  public GetItemsAllResponse getItemsAll(String id) {
    GetItemsAllRequest request = GetItemsAllRequest.newBuilder().setId(id).build();
    return blockingStub.getItemsAll(request);
  }

  public GetByIdsResponse getByIds(List<String> listPartnerIds) {
    GetByIdsRequest request = GetByIdsRequest.newBuilder().addAllIds(listPartnerIds).build();
    return blockingStub.getByIds(request);
  }

  public Partners.Filter partnerFilter(String field, String value, String type, String operator) {
    Partners.Filter.Builder builder = Partners.Filter.newBuilder();
    if (field != null) builder.setField(field);
    if (value != null) builder.setValue(value);
    if (type != null) builder.setType(type);
    if (operator != null) builder.setOperator(operator);

    return builder.build();
  }

  public Partners.GetAllPagedResponse getPartnersAllPaged(
      int limit,
      int offset,
      List<Partners.GetAllPagedSort> sort,
      List<Partners.Filter> listFilters,
      Boolean count,
      List<String> projection) {
    Partners.GetAllPagedRequest.Builder builder =
        Partners.GetAllPagedRequest.newBuilder().setLimit(limit).setOffset(offset);
    if (sort != null) builder.addAllSort(sort);
    if (listFilters != null) builder.addAllFilters(listFilters);
    if (count != null) builder.setDisableTotalCount(count);
    if (projection != null) builder.addAllProjection(projection);

    return blockingStub.getAllPaged(builder.build());
  }

  public Partners.CreateResponse createPartner(Partners.Partner request) {
    Partners.CreateRequest create =
        Partners.CreateRequest.newBuilder().setDocument(request).build();
    return blockingStub.create(create);
  }

  public Partners.UpdateFieldsResponse getUpdateFields(
      String id, List<String> updatedFields, tv.pluto.ip.dal.partner.Partners.Partner partner) {
    Partners.UpdateFieldsRequest request =
        Partners.UpdateFieldsRequest.newBuilder()
            .setId(id)
            .setDocument(partner)
            .addAllUpdateFields(updatedFields)
            .build();
    return blockingStub.updateFields(request);
  }

  public Partners.GetByApiAuthorNameResponse getByApiAuthorName(String apiAuthorName) {
    Partners.GetByApiAuthorNameRequest.Builder builder =
        Partners.GetByApiAuthorNameRequest.newBuilder();

    if (apiAuthorName != null) builder.setApiAuthorName(apiAuthorName);

    return blockingStub.getByApiAuthorName(builder.build());
  }

  public Partners.GetByFilterResponse getByFilter(
      Boolean is_id, String api_author_name, String partner) {
    Partners.GetByFilterRequest.Builder builder =
        Partners.GetByFilterRequest.newBuilder().setIsId(is_id);

    if (api_author_name != null) {
      builder.setApiAuthorName(api_author_name);
    }

    if (partner != null) {
      builder.setPartnerId(partner);
    }

    Partners.GetByFilterRequest request = builder.build();
    return blockingStub.getByFilter(request);
  }
}
