/*
 *
 * Copyright 2016 gRPC authors.
 *
 * Licensed 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.
 *
 */

#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H

#include <grpc/support/port_platform.h>

#include <vector>

#include <grpc/slice_buffer.h>

#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/proto/grpc/lb/v1/load_balancer.upb.h"

#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
#define GRPC_GRPCLB_SERVER_IP_ADDRESS_MAX_SIZE 16
#define GRPC_GRPCLB_SERVER_LOAD_BALANCE_TOKEN_MAX_SIZE 50

namespace grpc_core {

// Contains server information. When the drop field is not true, use the other
// fields.
struct GrpcLbServer {
  int32_t ip_size;
  char ip_addr[GRPC_GRPCLB_SERVER_IP_ADDRESS_MAX_SIZE];
  int32_t port;
  char load_balance_token[GRPC_GRPCLB_SERVER_LOAD_BALANCE_TOKEN_MAX_SIZE];
  bool drop;

  bool operator==(const GrpcLbServer& other) const;
};

struct GrpcLbResponse {
  enum { INITIAL, SERVERLIST, FALLBACK } type;
  grpc_millis client_stats_report_interval = 0;
  std::vector<GrpcLbServer> serverlist;
};

// Creates a serialized grpclb request.
grpc_slice GrpcLbRequestCreate(const char* lb_service_name, upb_arena* arena);

// Creates a serialized grpclb load report request.
grpc_slice GrpcLbLoadReportRequestCreate(
    int64_t num_calls_started, int64_t num_calls_finished,
    int64_t num_calls_finished_with_client_failed_to_send,
    int64_t num_calls_finished_known_received,
    const GrpcLbClientStats::DroppedCallCounts* drop_token_counts,
    upb_arena* arena);

// Deserialize a grpclb response.
bool GrpcLbResponseParse(const grpc_slice& serialized_response,
                         upb_arena* arena, GrpcLbResponse* result);

}  // namespace grpc_core

#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H \
        */
