// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/kazoo/output_util.h"
#include "tools/kazoo/outputs.h"
#include "tools/kazoo/string_util.h"

namespace {

// This is almost list SplitString() on spaces, but punctuation needs to be treated differently as
// it's broken on, but not discarded (for example, '-' in the middle of words, or '.' attached the
// last word of a sentence.)
//
// TODO(syscall-fidl-transition): 1) This is probably more particular than consumers of the .json
// file really are; 2) There may only be one consumer of this field anyway (update-docs-from-abigen)
// which is in-tree and can just be rewritten in some other way.
std::vector<std::string> BreakAsAbigenParser(const std::string& docstr) {
  std::vector<std::string> tokens;
  std::string tok;

  for (const auto& c : docstr) {
    if (isalnum(c) || c == '_') {
      tok += c;
    } else {
      if (!tok.empty())
        tokens.push_back(tok);
      tok.clear();
      if (ispunct(c))
        tokens.emplace_back(1, c);
    }
  }
  if (!tok.empty())
    tokens.push_back(tok);

  return tokens;
}

}  // namespace

bool JsonOutput(const SyscallLibrary& library, Writer* writer) {
  // Note, no comments allowed in plain json, so no copyright or "is generated" note.

  writer->Puts("{\n");

  writer->Puts("  \"syscalls\": [\n");
  for (size_t j = 0; j < library.syscalls().size(); ++j) {
    const auto& syscall = *library.syscalls()[j];
    writer->Puts("    {\n");
    std::string indent("      ");

    auto iprintn = [&indent, &writer](const char* format, ...) {
      writer->Puts(indent.c_str());
      va_list ap;
      va_start(ap, format);
      std::string result = StringVPrintf((format + std::string("\n")).c_str(), ap);
      va_end(ap);
      return writer->Puts(result);
    };

    auto output_list = [&iprintn](const std::vector<std::string>& items) {
      for (size_t i = 0; i < items.size(); ++i) {
        iprintn("\"%s\"%s", items[i].c_str(), i == items.size() - 1 ? "" : ",");
      }
    };
    auto in = [&indent]() { indent += "  "; };
    auto out = [&indent]() { indent = indent.substr(2); };
    auto output_attributes_list = [&output_list](const auto& attrib_map) {
      std::vector<std::string> items;
      items.push_back("*");  // From abigen.
      for (const auto& it : attrib_map) {
        if (it.first == "Doc" || it.first == "ArgReorder") {
          continue;
        }
        items.push_back(CamelToSnake(it.first));
      }
      output_list(items);
    };

    iprintn("\"name\": \"%s\",", syscall.name().c_str());

    iprintn("\"attributes\": [");
    in();
    output_attributes_list(syscall.attributes());
    out();
    iprintn("],");

    iprintn("\"top_description\": [");
    in();
    const auto doc_split = BreakAsAbigenParser(syscall.short_description());
    if (!doc_split.empty()) {
      iprintn(("\"" + JoinStrings(doc_split, "\", \"") + "\"").c_str());
    }
    out();
    iprintn("],");

    iprintn("\"requirements\": [");
    in();
    for (size_t i = 0; i < syscall.rights_specs().size(); ++i) {
      std::string rights = syscall.rights_specs()[i];
      const bool last_right = i == syscall.rights_specs().size() - 1;
      iprintn("%s%s", ("\"" + JoinStrings(BreakAsAbigenParser(rights), "\", \"") + "\"").c_str(),
              last_right ? "" : ",");
    }
    out();
    iprintn("],");

    iprintn("\"arguments\": [");
    in();
    for (size_t i = 0; i < syscall.kernel_arguments().size(); ++i) {
      const auto& arg = syscall.kernel_arguments()[i];
      iprintn("{");
      in();
      iprintn("\"name\": \"%s\",", arg.name().c_str());
      auto type_info = GetJsonName(arg.type());
      iprintn("\"type\": \"%s\",", type_info.name.c_str());
      iprintn("\"is_array\": %s,", type_info.is_pointer ? "true" : "false");
      iprintn("\"attributes\": [");
      if (type_info.attribute == "IN") {
        iprintn("  \"IN\"");
      }
      iprintn("]");
      out();
      const bool last_arg = i == syscall.kernel_arguments().size() - 1;
      iprintn("}%s", last_arg ? "" : ",");
    }
    out();
    iprintn("],");

    iprintn("\"return_type\": \"%s\"", GetCUserModeName(syscall.kernel_return_type()).c_str());

    const bool last_syscall = j == library.syscalls().size() - 1;
    writer->Printf("    }%s\n", last_syscall ? "" : ",");
  }
  writer->Puts("  ]\n");
  writer->Puts("}\n");

  return true;
}
