/*
 *
 * Copyright 2015 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.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/lib/surface/event_string.h"

#include <stdio.h>

#include <grpc/byte_buffer.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"

static void addhdr(gpr_strvec* buf, grpc_event* ev) {
  char* tmp;
  gpr_asprintf(&tmp, "tag:%p", ev->tag);
  gpr_strvec_add(buf, tmp);
}

static const char* errstr(int success) { return success ? "OK" : "ERROR"; }

static void adderr(gpr_strvec* buf, int success) {
  char* tmp;
  gpr_asprintf(&tmp, " %s", errstr(success));
  gpr_strvec_add(buf, tmp);
}

char* grpc_event_string(grpc_event* ev) {
  char* out;
  gpr_strvec buf;

  if (ev == nullptr) return gpr_strdup("null");

  gpr_strvec_init(&buf);

  switch (ev->type) {
    case GRPC_QUEUE_TIMEOUT:
      gpr_strvec_add(&buf, gpr_strdup("QUEUE_TIMEOUT"));
      break;
    case GRPC_QUEUE_SHUTDOWN:
      gpr_strvec_add(&buf, gpr_strdup("QUEUE_SHUTDOWN"));
      break;
    case GRPC_OP_COMPLETE:
      gpr_strvec_add(&buf, gpr_strdup("OP_COMPLETE: "));
      addhdr(&buf, ev);
      adderr(&buf, ev->success);
      break;
  }

  out = gpr_strvec_flatten(&buf, nullptr);
  gpr_strvec_destroy(&buf);
  return out;
}
