/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/traceconv/trace_to_json.h"

#include <stdio.h>

#include "perfetto/base/logging.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/trace_processor/trace_processor.h"
#include "src/traceconv/utils.h"

namespace perfetto {
namespace trace_to_text {

namespace {

const char kTraceHeader[] = R"({
  "traceEvents": [],
)";

const char kTraceFooter[] = R"(,
  "controllerTraceDataKey": "systraceController"
})";

bool ExportUserspaceEvents(trace_processor::TraceProcessor* tp,
                           TraceWriter* writer) {
  fprintf(stderr, "Converting userspace events%c", kProgressChar);
  fflush(stderr);

  // Write userspace trace to a temporary file.
  // TODO(eseckler): Support streaming the result out of TP directly instead.
  auto file = base::TempFile::Create();
  char query[100];
  sprintf(query, "select export_json(\"%s\")", file.path().c_str());
  auto it = tp->ExecuteQuery(query);

  if (!it.Next()) {
    auto status = it.Status();
    PERFETTO_CHECK(!status.ok());
    PERFETTO_ELOG("Could not convert userspace events: %s", status.c_message());
    return false;
  }

  base::ScopedFstream source(fopen(file.path().c_str(), "r"));
  if (!source) {
    PERFETTO_ELOG("Could not convert userspace events: Couldn't read file %s",
                  file.path().c_str());
    return false;
  }

  char buf[BUFSIZ];
  size_t size;
  while ((size = fread(buf, sizeof(char), BUFSIZ, *source)) > 0) {
    // Skip writing the closing brace since we'll append system trace data.
    if (feof(*source))
      size--;
    writer->Write(buf, size);
  }
  return true;
}

}  // namespace

int TraceToJson(std::istream* input,
                std::ostream* output,
                bool compress,
                Keep truncate_keep,
                bool full_sort) {
  std::unique_ptr<TraceWriter> trace_writer(
      compress ? new DeflateTraceWriter(output) : new TraceWriter(output));

  trace_processor::Config config;
  config.sorting_mode = full_sort
                            ? trace_processor::SortingMode::kForceFullSort
                            : trace_processor::SortingMode::kDefaultHeuristics;
  std::unique_ptr<trace_processor::TraceProcessor> tp =
      trace_processor::TraceProcessor::CreateInstance(config);

  if (!ReadTraceUnfinalized(tp.get(), input))
    return 1;
  tp->NotifyEndOfFile();

  // TODO(eseckler): Support truncation of userspace event data.
  if (ExportUserspaceEvents(tp.get(), trace_writer.get())) {
    trace_writer->Write(",\n");
  } else {
    trace_writer->Write(kTraceHeader);
  }

  int ret = ExtractSystrace(tp.get(), trace_writer.get(),
                            /*wrapped_in_json=*/true, truncate_keep);
  if (ret)
    return ret;

  trace_writer->Write(kTraceFooter);
  return 0;
}

}  // namespace trace_to_text
}  // namespace perfetto
