//===--- tracer.cpp -------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "sourcekitd/Internal-XPC.h"
#include "sourcekitd/XpcTracing.h"

#include "SourceKit/Support/Logging.h"
#include "SourceKit/Support/Concurrency.h"

#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TimeValue.h"
#include "llvm/Support/YAMLTraits.h"

#include <xpc/xpc.h>

#include <algorithm>
#include <deque>
#include <functional>
#include <iomanip>
#include <map>
#include <set>

using namespace llvm;
using namespace sourcekitd;



//----------------------------------------------------------------------------//
// Generic
//----------------------------------------------------------------------------//

static std::string trace_root_dir;

bool isTracingEnabled() {
  return !trace_root_dir.empty();
}

typedef SmallString<256> path_t;
static llvm::sys::Mutex FileOpMutex;

static void fsEnsureDirExists(const char *Dir) {
  llvm::sys::ScopedLock L(FileOpMutex);
  if (!sys::fs::exists(Dir)) {
    sys::fs::create_directory(Dir);
  }
}

static void fsWriteFile(const char *Path, StringRef Text) {
  llvm::sys::ScopedLock L(FileOpMutex);
  if (!sys::fs::exists(Path)) {
    std::error_code EC;
    raw_fd_ostream Outfile(Path, EC, sys::fs::F_Text);
    Outfile << Text;
    Outfile.close();
  }
}

static void fsInitTraceRoot(path_t &RootDir, uint64_t Id) {
  RootDir = trace_root_dir;
  std::string DirName = llvm::sys::TimeValue::now().str();
  std::for_each(DirName.begin(), DirName.end(),
                [] (char &C) { if (!isalnum(C)) C = '-'; });
  DirName += '-';
  DirName += std::to_string(Id);
  sys::path::append(RootDir, DirName);
}

static void fsAddFileWithRevision(path_t &Path,
                                  const std::string &File,
                                  uint64_t Id) {
  sys::path::append(Path,
                    sys::path::stem(File) +
                    "." +
                    std::to_string(Id) +
                    sys::path::extension(File));
}

typedef SourceKit::trace::OperationKind OperationKind;

struct OperationInfo {
  sys::TimeValue StartedAt;
  OperationKind Kind;
  std::string SwiftArgs;
  trace::StringPairs OpArgs;
  trace::StringPairs Files;

  OperationInfo(OperationKind K,
                std::string &&SwiftArgs,
                trace::StringPairs &&Files,
                trace::StringPairs &&OpArgs)
    : StartedAt(sys::TimeValue::now()),
      Kind(K), SwiftArgs(SwiftArgs), OpArgs(OpArgs), Files(Files) {}

  OperationInfo() = default;
  OperationInfo(OperationInfo &&) = default;
  OperationInfo &operator=(OperationInfo &&) = default;

  OperationInfo(const OperationInfo &) = delete;
  OperationInfo &operator=(const OperationInfo &) = delete;
};

struct OpRec {
  std::string StartedAt;
  std::string OpName;
  std::string SwiftArgs;
  trace::StringPairs OpArgs;
  trace::StringPairs FileMap;
};

template <typename U>
struct llvm::yaml::SequenceTraits<std::vector<U>> {
  static size_t size(IO &Io, std::vector<U> &Vec) {
    return Vec.size();
  }
  static U &element(IO &Io, std::vector<U> &Vec, size_t Index) {
    return Vec[Index];
  }
};

template <>
struct llvm::yaml::MappingTraits<OpRec> {
  static void mapping(IO &Io, OpRec &Rec) {
    Io.mapRequired("op", Rec.OpName);
    Io.mapRequired("swift-args", Rec.SwiftArgs);
    Io.mapRequired("op-args", Rec.OpArgs);
    Io.mapRequired("file-map", Rec.FileMap);
  }
};

template <typename U, typename V>
struct llvm::yaml::MappingTraits<std::pair<U, V>> {
  static void mapping(IO &Io, std::pair<U, V> &Pair) {
    Io.mapRequired("first", Pair.first);
    Io.mapRequired("second", Pair.second);
  }
};



//----------------------------------------------------------------------------//
// State
//----------------------------------------------------------------------------//

class State {
  typedef std::map<uint64_t, OperationInfo> OperationsType;

  static sys::Mutex GlobalMutex;
  sys::Mutex LocalMutex;

  static std::shared_ptr<State> CurrentState;
  static SourceKit::WorkQueue Queue;
  static std::string CompArgsFile;
  static std::string ActiveOpFile;

  const uint64_t Id;
  std::atomic<uint64_t> UniqueId;
  std::string TraceDir;

  std::set<uint64_t> ReportedOps;
  std::set<uint64_t> SeenOps;
  OperationsType Operations;

  State(uint64_t Id) : Id(Id), UniqueId(0) {
  }

  void persist();

  static std::shared_ptr<State> getState(uint64_t Session) {
    llvm::sys::ScopedLock L(GlobalMutex);

    if (!CurrentState) {
      CurrentState.reset(new State(Session));
    } else if (!CurrentState || CurrentState->Id != Session) {
      auto S = CurrentState;
      Queue.dispatch([S] {S->persist();});
      CurrentState.reset(new State(Session));
    }
    return CurrentState;
  }

public:
  State(const State &) = delete;
  State &operator=(const State &) = delete;
  State(State &&) = delete;
  State &operator=(State &&) = delete;

  static void addOperation(uint64_t Session,
                           uint64_t OpId,
                           OperationKind Kind,
                           std::string &&SwiftArgs,
                           trace::StringPairs &&Files,
                           trace::StringPairs &&OpArgs) {
    auto S = getState(Session);
    llvm::sys::ScopedLock L(S->LocalMutex);
    assert(S->SeenOps.find(OpId) == S->SeenOps.end());
    S->Operations[OpId] = OperationInfo(
      Kind, std::move(SwiftArgs), std::move(Files), std::move(OpArgs));
    S->SeenOps.insert(OpId);
  }

  static void removeOperation(uint64_t Session,
                              uint64_t OpId) {
    auto S = getState(Session);
    llvm::sys::ScopedLock L(S->LocalMutex);
    assert(S->Operations.find(OpId) != S->Operations.end());
    S->Operations.erase(OpId);
  }

  static void persistAsync(bool WithActions) {
    llvm::sys::ScopedLock L(GlobalMutex);
    auto S = CurrentState;
    Queue.dispatch([S] {S->persist();});
  }
};

std::shared_ptr<State> State::CurrentState;
sys::Mutex State::GlobalMutex;
std::string State::CompArgsFile("swift-args.txt");
std::string State::ActiveOpFile("active-operation.txt");

SourceKit::WorkQueue State::Queue {
  SourceKit::WorkQueue::Dequeuing::Serial, "sourcekit.swift.tracer.state"
};

static std::map<OperationKind, std::string> op_kind_names {
  std::make_pair(OperationKind::SimpleParse, "SimpleParse"),
  std::make_pair(OperationKind::PerformSema, "PerformSema"),
  std::make_pair(OperationKind::AnnotAndDiag, "AnnotAndDiag"),
  std::make_pair(OperationKind::OpenInterface, "OpenInterface"),
  std::make_pair(OperationKind::ReadDiagnostics, "ReadDiagnostics"),
  std::make_pair(OperationKind::ReadSemanticInfo, "ReadSemanticInfo"),
  std::make_pair(OperationKind::ReadSyntaxInfo, "ReadSyntaxInfo"),
  std::make_pair(OperationKind::IndexModule, "IndexModule"),
  std::make_pair(OperationKind::IndexSource, "IndexSource"),
  std::make_pair(OperationKind::CursorInfoForIFaceGen, "CursorInfoForIFaceGen"),
  std::make_pair(OperationKind::CursorInfoForSource, "CursorInfoForSource"),
  std::make_pair(OperationKind::RelatedIdents, "RelatedIdents"),
  std::make_pair(OperationKind::FormatText, "FormatText"),
  std::make_pair(OperationKind::ExpandPlaceholder, "ExpandPlaceholder"),
  std::make_pair(OperationKind::CodeCompletion, "CodeCompletion"),
  std::make_pair(OperationKind::CodeCompletionInit, "CodeCompletionInit"),
};

void State::persist() {
  llvm::sys::ScopedLock L(LocalMutex);

  if (TraceDir.empty()) {
    path_t RootDir;
    fsInitTraceRoot(RootDir, Id);
    TraceDir = RootDir.c_str();
  }
  fsEnsureDirExists(TraceDir.c_str());

  path_t FilePath;

  std::for_each(
    Operations.begin(), Operations.end(),
    [&] (OperationsType::value_type &Pair) {
      if (ReportedOps.find(Pair.first) == ReportedOps.end()) {
        ReportedOps.insert(Pair.first);

        auto &Op = Pair.second;

        OpRec Rec;
        Rec.OpName = op_kind_names[Op.Kind];
        Rec.OpArgs = Op.OpArgs;

        // Dump Swift arguments
        FilePath = TraceDir;
        fsAddFileWithRevision(FilePath, CompArgsFile, ++UniqueId);
        Rec.SwiftArgs = FilePath.c_str();
        fsWriteFile(FilePath.c_str(), Op.SwiftArgs);

        // Dump files
        std::for_each(
          Op.Files.begin(), Op.Files.end(),
          [&] (trace::StringPairs::value_type &Pair) {
            FilePath = TraceDir;
            fsAddFileWithRevision(FilePath, Pair.first, ++UniqueId);
            Rec.FileMap.push_back(std::make_pair(Pair.first, FilePath.c_str()));
            fsWriteFile(FilePath.c_str(), Pair.second);
          });

        // Serialize operation info
        FilePath = TraceDir;
        fsAddFileWithRevision(FilePath, ActiveOpFile, Pair.first);
        std::error_code EC;
        raw_fd_ostream Outfile(FilePath, EC, sys::fs::F_Text);
        llvm::yaml::Output YamlOutput(Outfile);
        YamlOutput << Rec;
      }
    });
}



//----------------------------------------------------------------------------//
// Init & trace
//----------------------------------------------------------------------------//

void initializeTracing() {
  const char *EnvOpt = ::getenv("SOURCEKIT_TRACE_ROOT");
  if (EnvOpt) {
    using namespace SourceKit;
    LOG_WARN_FUNC("TRACE: Enabled with root: " << EnvOpt);
    trace_root_dir = EnvOpt;
  }
}

static uint32_t readUint64(xpc_object_t Arr, size_t Index) {
  return xpc_array_get_uint64(Arr, Index);
}

static trace::ActionKind readAction(xpc_object_t Arr, size_t Index) {
  return static_cast<trace::ActionKind>(readUint64(Arr, Index));
}

static trace::OperationKind readOpKind(xpc_object_t Arr, size_t Index) {
  return static_cast<trace::OperationKind>(readUint64(Arr, Index));
}

static llvm::StringRef readString(xpc_object_t Arr, size_t Index) {
  return xpc_array_get_string(Arr, Index);
}

static trace::StringPairs readStringPairs(xpc_object_t Arr, size_t &Index) {
  trace::StringPairs Files;
  auto Count = readUint64(Arr, Index++);
  for (uint64_t I = 0; I < Count; I++) {
    auto FileName = readString(Arr, Index++);
    auto Text = readString(Arr, Index++);
    Files.push_back(std::make_pair(FileName, Text));
  }
  return Files;
}

void handleTraceMessageRequest(uint64_t Session, xpc_object_t Msg) {
  if (isTracingEnabled()) {
    if (xpc_get_type(Msg) == XPC_TYPE_ARRAY) {
      switch (readAction(Msg, 0)) {

      case trace::ActionKind::OperationStarted: {
        size_t Index = 4;
        auto Files = readStringPairs(Msg, Index);
        auto OpArgs = readStringPairs(Msg, Index);
        State::addOperation(Session,
                            readUint64(Msg, 1),
                            readOpKind(Msg, 2),
                            readString(Msg, 3),
                            std::move(Files),
                            std::move(OpArgs));
        break;
      }
        
      case trace::ActionKind::OperationFinished: {
        State::removeOperation(Session, readUint64(Msg, 1));
        break;
      }
          
      }

    } else {
      llvm::report_fatal_error("Unknown trace message");
    }
  }
}

void persistTracingData() {
  if (isTracingEnabled()) {
    State::persistAsync(true);
  }
}

