// 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) {
        const auto& attr_name = CamelToSnake(it.first);
        if (attr_name == "doc" || attr_name == "arg_reorder") {
          continue;
        }
        items.push_back(attr_name);
      }
      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;
}
