//===--- api_notes.cpp - Swift Compiler Frontend --------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This is the YAML to binary converter for API notes.
///
//===----------------------------------------------------------------------===//
#include "clang/APINotes/APINotesYAMLCompiler.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Triple.h"

using namespace llvm;
namespace api_notes = clang::api_notes;

int apinotes_main(ArrayRef<const char *> Args) {

  // Mark all our options with this category, everything else (except for
  // -version and -help) will be hidden.
  static cl::OptionCategory APINotesCategory("API Notes options");

  static cl::opt<api_notes::ActionType>
  Action(cl::desc("Mode:"), cl::init(api_notes::ActionType::None),
         cl::values(
                    clEnumValN(api_notes::ActionType::YAMLToBinary,
                            "yaml-to-binary", "Convert YAML to binary format"),
                    clEnumValN(api_notes::ActionType::BinaryToYAML,
                               "binary-to-yaml",
                               "Convert binary format to YAML"),
                    clEnumValN(api_notes::ActionType::Dump,
                            "dump", "Parse and dump the output")),
         cl::cat(APINotesCategory));

  static cl::opt<std::string>
  InputFilename(cl::Positional, cl::desc("<input file>"),
                cl::Required, cl::cat(APINotesCategory));

  static cl::opt<std::string>
  Target("target", cl::desc("Generate binary format for the given target"),
                   cl::cat(APINotesCategory));

  static cl::opt<std::string>
  OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));

  // Hide unrelated options.
  StringMap<cl::Option *> &Options =
      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
  for (auto &Option : Options) {
    if (Option.second->Category != &APINotesCategory &&
        Option.first() != "help" && Option.first() != "version") {
      Option.second->setHiddenFlag(cl::ReallyHidden);
    }
  }

  cl::ParseCommandLineOptions(Args.size(),
                              Args.data(),
                              "Swift API Notes Tool\n");

  if (Action == clang::api_notes::ActionType::None) {
    errs() << "action required\n";
    cl::PrintHelpMessage();
    return 1;
  }

  auto fileBufOrErr = MemoryBuffer::getFile(InputFilename);
  if (std::error_code EC = fileBufOrErr.getError()) {
    llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
    return true;
  }
  StringRef input = fileBufOrErr.get()->getBuffer();

  switch (Action) {
  case api_notes::ActionType::None:
    llvm_unreachable("handled above");

  case api_notes::ActionType::YAMLToBinary: {
    if (OutputFilename.empty()) {
      errs() << "output file is required\n";
      cl::PrintHelpMessage();
      return 1;
    }

    api_notes::OSType targetOS = api_notes::OSType::Absent;
    // TODO: Check that we've specified the target.
    if (!Target.empty()) {
      llvm::Triple target(llvm::Triple::normalize(Target));
      switch (target.getOS()) {
        case llvm::Triple::Darwin:
        case llvm::Triple::MacOSX:
          targetOS = api_notes::OSType::OSX;
          break;
        case llvm::Triple::IOS:
          targetOS = api_notes::OSType::IOS;
          break;
        case llvm::Triple::TvOS:
          targetOS = api_notes::OSType::TvOS;
          break;
        case llvm::Triple::WatchOS:
          targetOS = api_notes::OSType::WatchOS;
          break;
        default:
          errs() << "target is not supported\n";
          return 1;
      }
    }
    std::error_code EC;
    llvm::raw_fd_ostream os(OutputFilename, EC,
                            llvm::sys::fs::OpenFlags::F_None);

    if (api_notes::compileAPINotes(input, /*sourceFile=*/nullptr, os, targetOS))
      return 1;
    
    os.flush();

    return os.has_error();
  }

  case api_notes::ActionType::BinaryToYAML: {
    if (OutputFilename.empty()) {
      errs() << "output file required\n";
      cl::PrintHelpMessage();
      return 1;
    }

    std::error_code EC;
    llvm::raw_fd_ostream os(OutputFilename, EC,
                            llvm::sys::fs::OpenFlags::F_None);

    if (api_notes::decompileAPINotes(std::move(fileBufOrErr.get()), os))
      return 1;
    
    os.flush();

    return os.has_error();
  }

  case api_notes::ActionType::Dump:
    return api_notes::parseAndDumpAPINotes(input);
  }

  return 1;
}

