// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "exception.h"
#include "string.h"
#include "debug.h"
#include "threadlocal.h"
#include "miniposix.h"
#include <stdlib.h>
#include <exception>
#include <new>
#include <signal.h>
#ifndef _WIN32
#include <sys/mman.h>
#endif
#include "io.h"

#if (__linux__ && __GLIBC__) || __APPLE__
#define KJ_HAS_BACKTRACE 1
#include <execinfo.h>
#endif

#if _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "windows-sanity.h"
#include <dbghelp.h>
#endif

#if (__linux__ || __APPLE__)
#include <stdio.h>
#include <pthread.h>
#endif

namespace kj {

StringPtr KJ_STRINGIFY(LogSeverity severity) {
  static const char* SEVERITY_STRINGS[] = {
    "info",
    "warning",
    "error",
    "fatal",
    "debug"
  };

  return SEVERITY_STRINGS[static_cast<uint>(severity)];
}

#if _WIN32 && _M_X64
// Currently the Win32 stack-trace code only supports x86_64. We could easily extend it to support
// i386 as well but it requires some code changes around how we read the context to start the
// trace.

namespace {

struct Dbghelp {
  // Load dbghelp.dll dynamically since we don't really need it, it's just for debugging.

  HINSTANCE lib;

  BOOL (WINAPI *symInitialize)(HANDLE hProcess,PCSTR UserSearchPath,BOOL fInvadeProcess);
  BOOL (WINAPI *stackWalk64)(
      DWORD MachineType,HANDLE hProcess,HANDLE hThread,
      LPSTACKFRAME64 StackFrame,PVOID ContextRecord,
      PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
      PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
      PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
      PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
  PVOID (WINAPI *symFunctionTableAccess64)(HANDLE hProcess,DWORD64 AddrBase);
  DWORD64 (WINAPI *symGetModuleBase64)(HANDLE hProcess,DWORD64 qwAddr);
  BOOL (WINAPI *symGetLineFromAddr64)(
      HANDLE hProcess,DWORD64 qwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE64 Line64);

  Dbghelp()
      : lib(LoadLibraryA("dbghelp.dll")),
        symInitialize(lib == nullptr ? nullptr :
            reinterpret_cast<decltype(symInitialize)>(
                GetProcAddress(lib, "SymInitialize"))),
        stackWalk64(symInitialize == nullptr ? nullptr :
            reinterpret_cast<decltype(stackWalk64)>(
                GetProcAddress(lib, "StackWalk64"))),
        symFunctionTableAccess64(symInitialize == nullptr ? nullptr :
            reinterpret_cast<decltype(symFunctionTableAccess64)>(
                GetProcAddress(lib, "SymFunctionTableAccess64"))),
        symGetModuleBase64(symInitialize == nullptr ? nullptr :
            reinterpret_cast<decltype(symGetModuleBase64)>(
                GetProcAddress(lib, "SymGetModuleBase64"))),
        symGetLineFromAddr64(symInitialize == nullptr ? nullptr :
            reinterpret_cast<decltype(symGetLineFromAddr64)>(
                GetProcAddress(lib, "SymGetLineFromAddr64"))) {
    if (symInitialize != nullptr) {
      symInitialize(GetCurrentProcess(), NULL, TRUE);
    }
  }
};

const Dbghelp& getDbghelp() {
  static Dbghelp dbghelp;
  return dbghelp;
}

ArrayPtr<void* const> getStackTrace(ArrayPtr<void*> space, uint ignoreCount,
                                    HANDLE thread, CONTEXT& context) {
  const Dbghelp& dbghelp = getDbghelp();
  if (dbghelp.stackWalk64 == nullptr ||
      dbghelp.symFunctionTableAccess64 == nullptr ||
      dbghelp.symGetModuleBase64 == nullptr) {
    return nullptr;
  }

  STACKFRAME64 frame;
  memset(&frame, 0, sizeof(frame));

  frame.AddrPC.Offset = context.Rip;
  frame.AddrPC.Mode = AddrModeFlat;
  frame.AddrStack.Offset = context.Rsp;
  frame.AddrStack.Mode = AddrModeFlat;
  frame.AddrFrame.Offset = context.Rbp;
  frame.AddrFrame.Mode = AddrModeFlat;

  HANDLE process = GetCurrentProcess();

  uint count = 0;
  for (; count < space.size(); count++) {
    if (!dbghelp.stackWalk64(IMAGE_FILE_MACHINE_AMD64, process, thread,
          &frame, &context, NULL, dbghelp.symFunctionTableAccess64,
          dbghelp.symGetModuleBase64, NULL)){
      break;
    }

    space[count] = reinterpret_cast<void*>(frame.AddrPC.Offset);
  }

  return space.slice(kj::min(ignoreCount, count), count);
}

}  // namespace
#endif

ArrayPtr<void* const> getStackTrace(ArrayPtr<void*> space, uint ignoreCount) {
  if (getExceptionCallback().stackTraceMode() == ExceptionCallback::StackTraceMode::NONE) {
    return nullptr;
  }

#if _WIN32 && _M_X64
  CONTEXT context;
  RtlCaptureContext(&context);
  return getStackTrace(space, ignoreCount, GetCurrentThread(), context);
#elif KJ_HAS_BACKTRACE
  size_t size = backtrace(space.begin(), space.size());
  return space.slice(kj::min(ignoreCount + 1, size), size);
#else
  return nullptr;
#endif
}

String stringifyStackTrace(ArrayPtr<void* const> trace) {
  if (trace.size() == 0) return nullptr;
  if (getExceptionCallback().stackTraceMode() != ExceptionCallback::StackTraceMode::FULL) {
    return nullptr;
  }

#if _WIN32 && _M_X64 && _MSC_VER

  // Try to get file/line using SymGetLineFromAddr64(). We don't bother if we aren't on MSVC since
  // this requires MSVC debug info.
  //
  // TODO(someday): We could perhaps shell out to addr2line on MinGW.

  const Dbghelp& dbghelp = getDbghelp();
  if (dbghelp.symGetLineFromAddr64 == nullptr) return nullptr;

  HANDLE process = GetCurrentProcess();

  KJ_STACK_ARRAY(String, lines, trace.size(), 32, 32);

  for (auto i: kj::indices(trace)) {
    IMAGEHLP_LINE64 lineInfo;
    memset(&lineInfo, 0, sizeof(lineInfo));
    lineInfo.SizeOfStruct = sizeof(lineInfo);
    if (dbghelp.symGetLineFromAddr64(process, reinterpret_cast<DWORD64>(trace[i]), NULL, &lineInfo)) {
      lines[i] = kj::str('\n', lineInfo.FileName, ':', lineInfo.LineNumber);
    }
  }

  return strArray(lines, "");

#elif (__linux__ || __APPLE__) && !__ANDROID__
  // We want to generate a human-readable stack trace.

  // TODO(someday):  It would be really great if we could avoid farming out to another process
  //   and do this all in-process, but that may involve onerous requirements like large library
  //   dependencies or using -rdynamic.

  // The environment manipulation is not thread-safe, so lock a mutex.  This could still be
  // problematic if another thread is manipulating the environment in unrelated code, but there's
  // not much we can do about that.  This is debug-only anyway and only an issue when LD_PRELOAD
  // is in use.
  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&mutex);
  KJ_DEFER(pthread_mutex_unlock(&mutex));

  // Don't heapcheck / intercept syscalls.
  const char* preload = getenv("LD_PRELOAD");
  String oldPreload;
  if (preload != nullptr) {
    oldPreload = heapString(preload);
    unsetenv("LD_PRELOAD");
  }
  KJ_DEFER(if (oldPreload != nullptr) { setenv("LD_PRELOAD", oldPreload.cStr(), true); });

  String lines[32];
  FILE* p = nullptr;
  auto strTrace = strArray(trace, " ");

#if __linux__
  if (access("/proc/self/exe", R_OK) < 0) {
    // Apparently /proc is not available?
    return nullptr;
  }

  // Obtain symbolic stack trace using addr2line.
  // TODO(cleanup): Use fork() and exec() or maybe our own Subprocess API (once it exists), to
  //   avoid depending on a shell.
  p = popen(str("addr2line -e /proc/", getpid(), "/exe ", strTrace).cStr(), "r");
#elif __APPLE__
  // The Mac OS X equivalent of addr2line is atos.
  // (Internally, it uses the private CoreSymbolication.framework library.)
  p = popen(str("xcrun atos -p ", getpid(), ' ', strTrace).cStr(), "r");
#endif

  if (p == nullptr) {
    return nullptr;
  }

  char line[512];
  size_t i = 0;
  while (i < kj::size(lines) && fgets(line, sizeof(line), p) != nullptr) {
    // Don't include exception-handling infrastructure or promise infrastructure in stack trace.
    // addr2line output matches file names; atos output matches symbol names.
    if (strstr(line, "kj/common.c++") != nullptr ||
        strstr(line, "kj/exception.") != nullptr ||
        strstr(line, "kj/debug.") != nullptr ||
        strstr(line, "kj/async.") != nullptr ||
        strstr(line, "kj/async-prelude.h") != nullptr ||
        strstr(line, "kj/async-inl.h") != nullptr ||
        strstr(line, "kj::Exception") != nullptr ||
        strstr(line, "kj::_::Debug") != nullptr) {
      continue;
    }

    size_t len = strlen(line);
    if (len > 0 && line[len-1] == '\n') line[len-1] = '\0';
    lines[i++] = str("\n    ", trimSourceFilename(line), ": returning here");
  }

  // Skip remaining input.
  while (fgets(line, sizeof(line), p) != nullptr) {}

  pclose(p);

  return strArray(arrayPtr(lines, i), "");

#else
  return nullptr;
#endif
}

String getStackTrace() {
  void* space[32];
  auto trace = getStackTrace(space, 2);
  return kj::str(kj::strArray(trace, " "), stringifyStackTrace(trace));
}

#if _WIN32 && _M_X64
namespace {

DWORD mainThreadId = 0;

BOOL WINAPI breakHandler(DWORD type) {
  switch (type) {
    case CTRL_C_EVENT:
    case CTRL_BREAK_EVENT: {
      HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, mainThreadId);
      if (thread != NULL) {
        if (SuspendThread(thread) != (DWORD)-1) {
          CONTEXT context;
          memset(&context, 0, sizeof(context));
          context.ContextFlags = CONTEXT_FULL;
          if (GetThreadContext(thread, &context)) {
            void* traceSpace[32];
            auto trace = getStackTrace(traceSpace, 2, thread, context);
            ResumeThread(thread);
            auto message = kj::str("*** Received CTRL+C. stack: ", strArray(trace, " "),
                                   stringifyStackTrace(trace), '\n');
            FdOutputStream(STDERR_FILENO).write(message.begin(), message.size());
          } else {
            ResumeThread(thread);
          }
        }
        CloseHandle(thread);
      }
      break;
    }
    default:
      break;
  }

  return FALSE;  // still crash
}

}  // namespace

void printStackTraceOnCrash() {
  mainThreadId = GetCurrentThreadId();
  KJ_WIN32(SetConsoleCtrlHandler(breakHandler, TRUE));
}

#elif KJ_HAS_BACKTRACE
namespace {

void crashHandler(int signo, siginfo_t* info, void* context) {
  void* traceSpace[32];

  // ignoreCount = 2 to ignore crashHandler() and signal trampoline.
  auto trace = getStackTrace(traceSpace, 2);

  auto message = kj::str("*** Received signal #", signo, ": ", strsignal(signo),
                         "\nstack: ", strArray(trace, " "),
                         stringifyStackTrace(trace), '\n');

  FdOutputStream(STDERR_FILENO).write(message.begin(), message.size());
  _exit(1);
}

}  // namespace

void printStackTraceOnCrash() {
  // Set up alternate signal stack so that stack overflows can be handled.
  stack_t stack;
  memset(&stack, 0, sizeof(stack));

#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#ifndef MAP_GROWSDOWN
#define MAP_GROWSDOWN 0
#endif

  stack.ss_size = 65536;
  // Note: ss_sp is char* on FreeBSD, void* on Linux and OSX.
  stack.ss_sp = reinterpret_cast<char*>(mmap(
      nullptr, stack.ss_size, PROT_READ | PROT_WRITE,
      MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, -1, 0));
  KJ_SYSCALL(sigaltstack(&stack, nullptr));

  // Catch all relevant signals.
  struct sigaction action;
  memset(&action, 0, sizeof(action));

  action.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER | SA_RESETHAND;
  action.sa_sigaction = &crashHandler;

  // Dump stack on common "crash" signals.
  KJ_SYSCALL(sigaction(SIGSEGV, &action, nullptr));
  KJ_SYSCALL(sigaction(SIGBUS, &action, nullptr));
  KJ_SYSCALL(sigaction(SIGFPE, &action, nullptr));
  KJ_SYSCALL(sigaction(SIGABRT, &action, nullptr));
  KJ_SYSCALL(sigaction(SIGILL, &action, nullptr));

  // Dump stack on unimplemented syscalls -- useful in seccomp sandboxes.
  KJ_SYSCALL(sigaction(SIGSYS, &action, nullptr));

#ifdef KJ_DEBUG
  // Dump stack on keyboard interrupt -- useful for infinite loops. Only in debug mode, though,
  // because stack traces on ctrl+c can be obnoxious for, say, command-line tools.
  KJ_SYSCALL(sigaction(SIGINT, &action, nullptr));
#endif
}
#else
void printStackTraceOnCrash() {
}
#endif

kj::StringPtr trimSourceFilename(kj::StringPtr filename) {
  // Removes noisy prefixes from source code file name.
  //
  // The goal here is to produce the "canonical" filename given the filename returned by e.g.
  // addr2line. addr2line gives us the full path of the file as passed on the compiler
  // command-line, which in turn is affected by build system and by whether and where we're
  // performing an out-of-tree build.
  //
  // To deal with all this, we look for directory names in the path which we recognize to be
  // locations that represent roots of the source tree. We strip said root and everything before
  // it.
  //
  // On Windows, we often get filenames containing backslashes. Since we aren't allowed to allocate
  // a new string here, we can't do much about this, so our returned "canonical" name will
  // unfortunately end up with backslashes.

  static constexpr const char* ROOTS[] = {
    "ekam-provider/canonical/",  // Ekam source file.
    "ekam-provider/c++header/",  // Ekam include file.
    "src/",                      // Non-Ekam source root.
    "tmp/",                      // Non-Ekam generated code.
#if _WIN32
    "src\\",                     // Win32 source root.
    "tmp\\",                     // Win32 generated code.
#endif
  };

retry:
  for (size_t i: kj::indices(filename)) {
    if (i == 0 || filename[i-1] == '/'
#if _WIN32
               || filename[i-1] == '\\'
#endif
        ) {
      // We're at the start of a directory name. Check for valid prefixes.
      for (kj::StringPtr root: ROOTS) {
        if (filename.slice(i).startsWith(root)) {
          filename = filename.slice(i + root.size());

          // We should keep searching to find the last instance of a root name. `i` is no longer
          // a valid index for `filename` so start the loop over.
          goto retry;
        }
      }
    }
  }

  return filename;
}

StringPtr KJ_STRINGIFY(Exception::Type type) {
  static const char* TYPE_STRINGS[] = {
    "failed",
    "overloaded",
    "disconnected",
    "unimplemented"
  };

  return TYPE_STRINGS[static_cast<uint>(type)];
}

String KJ_STRINGIFY(const Exception& e) {
  uint contextDepth = 0;

  Maybe<const Exception::Context&> contextPtr = e.getContext();
  for (;;) {
    KJ_IF_MAYBE(c, contextPtr) {
      ++contextDepth;
      contextPtr = c->next;
    } else {
      break;
    }
  }

  Array<String> contextText = heapArray<String>(contextDepth);

  contextDepth = 0;
  contextPtr = e.getContext();
  for (;;) {
    KJ_IF_MAYBE(c, contextPtr) {
      contextText[contextDepth++] =
          str(c->file, ":", c->line, ": context: ", c->description, "\n");
      contextPtr = c->next;
    } else {
      break;
    }
  }

  return str(strArray(contextText, ""),
             e.getFile(), ":", e.getLine(), ": ", e.getType(),
             e.getDescription() == nullptr ? "" : ": ", e.getDescription(),
             e.getStackTrace().size() > 0 ? "\nstack: " : "", strArray(e.getStackTrace(), " "),
             stringifyStackTrace(e.getStackTrace()));
}

Exception::Exception(Type type, const char* file, int line, String description) noexcept
    : file(trimSourceFilename(file).cStr()), line(line), type(type), description(mv(description)),
      traceCount(0) {}

Exception::Exception(Type type, String file, int line, String description) noexcept
    : ownFile(kj::mv(file)), file(trimSourceFilename(ownFile).cStr()), line(line), type(type),
      description(mv(description)), traceCount(0) {}

Exception::Exception(const Exception& other) noexcept
    : file(other.file), line(other.line), type(other.type),
      description(heapString(other.description)), traceCount(other.traceCount) {
  if (file == other.ownFile.cStr()) {
    ownFile = heapString(other.ownFile);
    file = ownFile.cStr();
  }

  memcpy(trace, other.trace, sizeof(trace[0]) * traceCount);

  KJ_IF_MAYBE(c, other.context) {
    context = heap(**c);
  }
}

Exception::~Exception() noexcept {}

Exception::Context::Context(const Context& other) noexcept
    : file(other.file), line(other.line), description(str(other.description)) {
  KJ_IF_MAYBE(n, other.next) {
    next = heap(**n);
  }
}

void Exception::wrapContext(const char* file, int line, String&& description) {
  context = heap<Context>(file, line, mv(description), mv(context));
}

void Exception::extendTrace(uint ignoreCount) {
  KJ_STACK_ARRAY(void*, newTraceSpace, kj::size(trace) + ignoreCount + 1,
      sizeof(trace)/sizeof(trace[0]) + 8, 128);

  auto newTrace = kj::getStackTrace(newTraceSpace, ignoreCount + 1);
  if (newTrace.size() > ignoreCount + 2) {
    // Remove suffix that won't fit into our static-sized trace.
    newTrace = newTrace.slice(0, kj::min(kj::size(trace) - traceCount, newTrace.size()));

    // Copy the rest into our trace.
    memcpy(trace + traceCount, newTrace.begin(), newTrace.asBytes().size());
    traceCount += newTrace.size();
  }
}

void Exception::truncateCommonTrace() {
  if (traceCount > 0) {
    // Create a "reference" stack trace that is a little bit deeper than the one in the exception.
    void* refTraceSpace[sizeof(this->trace) / sizeof(this->trace[0]) + 4];
    auto refTrace = kj::getStackTrace(refTraceSpace, 0);

    // We expect that the deepest frame in the exception's stack trace should be somewhere in our
    // own trace, since our own trace has a deeper limit. Search for it.
    for (uint i = refTrace.size(); i > 0; i--) {
      if (refTrace[i-1] == trace[traceCount-1]) {
        // See how many frames match.
        for (uint j = 0; j < i; j++) {
          if (j >= traceCount) {
            // We matched the whole trace, apparently?
            traceCount = 0;
            return;
          } else if (refTrace[i-j-1] != trace[traceCount-j-1]) {
            // Found mismatching entry.

            // If we matched more than half of the reference trace, guess that this is in fact
            // the prefix we're looking for.
            if (j > refTrace.size() / 2) {
              // Delete the matching suffix. Also delete one non-matched entry on the assumption
              // that both traces contain that stack frame but are simply at different points in
              // the function.
              traceCount -= j + 1;
              return;
            }
          }
        }
      }
    }

    // No match. Ignore.
  }
}

void Exception::addTrace(void* ptr) {
  if (traceCount < kj::size(trace)) {
    trace[traceCount++] = ptr;
  }
}

class ExceptionImpl: public Exception, public std::exception {
public:
  inline ExceptionImpl(Exception&& other): Exception(mv(other)) {}
  ExceptionImpl(const ExceptionImpl& other): Exception(other) {
    // No need to copy whatBuffer since it's just to hold the return value of what().
  }

  const char* what() const noexcept override;

private:
  mutable String whatBuffer;
};

const char* ExceptionImpl::what() const noexcept {
  whatBuffer = str(*this);
  return whatBuffer.begin();
}

// =======================================================================================

namespace {

KJ_THREADLOCAL_PTR(ExceptionCallback) threadLocalCallback = nullptr;

}  // namespace

ExceptionCallback::ExceptionCallback(): next(getExceptionCallback()) {
  char stackVar;
  ptrdiff_t offset = reinterpret_cast<char*>(this) - &stackVar;
  KJ_ASSERT(offset < 65536 && offset > -65536,
            "ExceptionCallback must be allocated on the stack.");

  threadLocalCallback = this;
}

ExceptionCallback::ExceptionCallback(ExceptionCallback& next): next(next) {}

ExceptionCallback::~ExceptionCallback() noexcept(false) {
  if (&next != this) {
    threadLocalCallback = &next;
  }
}

void ExceptionCallback::onRecoverableException(Exception&& exception) {
  next.onRecoverableException(mv(exception));
}

void ExceptionCallback::onFatalException(Exception&& exception) {
  next.onFatalException(mv(exception));
}

void ExceptionCallback::logMessage(
    LogSeverity severity, const char* file, int line, int contextDepth, String&& text) {
  next.logMessage(severity, file, line, contextDepth, mv(text));
}

ExceptionCallback::StackTraceMode ExceptionCallback::stackTraceMode() {
  return next.stackTraceMode();
}

class ExceptionCallback::RootExceptionCallback: public ExceptionCallback {
public:
  RootExceptionCallback(): ExceptionCallback(*this) {}

  void onRecoverableException(Exception&& exception) override {
#if KJ_NO_EXCEPTIONS
    logException(LogSeverity::ERROR, mv(exception));
#else
    if (std::uncaught_exception()) {
      // Bad time to throw an exception.  Just log instead.
      //
      // TODO(someday): We should really compare uncaughtExceptionCount() against the count at
      //   the innermost runCatchingExceptions() frame in this thread to tell if exceptions are
      //   being caught correctly.
      logException(LogSeverity::ERROR, mv(exception));
    } else {
      throw ExceptionImpl(mv(exception));
    }
#endif
  }

  void onFatalException(Exception&& exception) override {
#if KJ_NO_EXCEPTIONS
    logException(LogSeverity::FATAL, mv(exception));
#else
    throw ExceptionImpl(mv(exception));
#endif
  }

  void logMessage(LogSeverity severity, const char* file, int line, int contextDepth,
                  String&& text) override {
    text = str(kj::repeat('_', contextDepth), file, ":", line, ": ", severity, ": ",
               mv(text), '\n');

    StringPtr textPtr = text;

    while (text != nullptr) {
      miniposix::ssize_t n = miniposix::write(STDERR_FILENO, textPtr.begin(), textPtr.size());
      if (n <= 0) {
        // stderr is broken.  Give up.
        return;
      }
      textPtr = textPtr.slice(n);
    }
  }

  StackTraceMode stackTraceMode() override {
#ifdef KJ_DEBUG
    return StackTraceMode::FULL;
#else
    return StackTraceMode::ADDRESS_ONLY;
#endif
  }

private:
  void logException(LogSeverity severity, Exception&& e) {
    // We intentionally go back to the top exception callback on the stack because we don't want to
    // bypass whatever log processing is in effect.
    //
    // We intentionally don't log the context since it should get re-added by the exception callback
    // anyway.
    getExceptionCallback().logMessage(severity, e.getFile(), e.getLine(), 0, str(
        e.getType(), e.getDescription() == nullptr ? "" : ": ", e.getDescription(),
        e.getStackTrace().size() > 0 ? "\nstack: " : "", strArray(e.getStackTrace(), " "),
        stringifyStackTrace(e.getStackTrace()), "\n"));
  }
};

ExceptionCallback& getExceptionCallback() {
  static ExceptionCallback::RootExceptionCallback defaultCallback;
  ExceptionCallback* scoped = threadLocalCallback;
  return scoped != nullptr ? *scoped : defaultCallback;
}

void throwFatalException(kj::Exception&& exception, uint ignoreCount) {
  exception.extendTrace(ignoreCount + 1);
  getExceptionCallback().onFatalException(kj::mv(exception));
  abort();
}

void throwRecoverableException(kj::Exception&& exception, uint ignoreCount) {
  exception.extendTrace(ignoreCount + 1);
  getExceptionCallback().onRecoverableException(kj::mv(exception));
}

// =======================================================================================

namespace _ {  // private

#if __GNUC__

// Horrible -- but working -- hack:  We can dig into __cxa_get_globals() in order to extract the
// count of uncaught exceptions.  This function is part of the C++ ABI implementation used on Linux,
// OSX, and probably other platforms that use GCC.  Unfortunately, __cxa_get_globals() is only
// actually defined in cxxabi.h on some platforms (e.g. Linux, but not OSX), and even where it is
// defined, it returns an incomplete type.  Here we use the same hack used by Evgeny Panasyuk:
//   https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp
//
// Notice that a similar hack is possible on MSVC -- if its C++11 support ever gets to the point of
// supporting KJ in the first place.
//
// It appears likely that a future version of the C++ standard may include an
// uncaught_exception_count() function in the standard library, or an equivalent language feature.
// Some discussion:
//   https://groups.google.com/a/isocpp.org/d/msg/std-proposals/HglEslyZFYs/kKdu5jJw5AgJ

struct FakeEhGlobals {
  // Fake

  void* caughtExceptions;
  uint uncaughtExceptions;
};

// Because of the 'extern "C"', the symbol name is not mangled and thus the namespace is effectively
// ignored for linking.  Thus it doesn't matter that we are declaring __cxa_get_globals() in a
// different namespace from the ABI's definition.
extern "C" {
FakeEhGlobals* __cxa_get_globals();
}

uint uncaughtExceptionCount() {
  // TODO(perf):  Use __cxa_get_globals_fast()?  Requires that __cxa_get_globals() has been called
  //   from somewhere.
  return __cxa_get_globals()->uncaughtExceptions;
}

#elif _MSC_VER

#if _MSC_VER >= 1900
// MSVC14 has a refactored CRT which now provides a direct accessor for this value.
// See https://svn.boost.org/trac/boost/ticket/10158 for a brief discussion.
extern "C" int *__cdecl __processing_throw();

uint uncaughtExceptionCount() {
  return static_cast<uint>(*__processing_throw());
}

#elif _MSC_VER >= 1400
// The below was copied from:
// https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp

extern "C" char *__cdecl _getptd();

uint uncaughtExceptionCount() {
  return *reinterpret_cast<uint*>(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90));
}
#else
uint uncaughtExceptionCount() {
  // Since the above doesn't work, fall back to uncaught_exception(). This will produce incorrect
  // results in very obscure cases that Cap'n Proto doesn't really rely on anyway.
  return std::uncaught_exception();
}
#endif

#else
#error "This needs to be ported to your compiler / C++ ABI."
#endif

}  // namespace _ (private)

UnwindDetector::UnwindDetector(): uncaughtCount(_::uncaughtExceptionCount()) {}

bool UnwindDetector::isUnwinding() const {
  return _::uncaughtExceptionCount() > uncaughtCount;
}

void UnwindDetector::catchExceptionsAsSecondaryFaults(_::Runnable& runnable) const {
  // TODO(someday):  Attach the secondary exception to whatever primary exception is causing
  //   the unwind.  For now we just drop it on the floor as this is probably fine most of the
  //   time.
  runCatchingExceptions(runnable);
}

namespace _ {  // private

class RecoverableExceptionCatcher: public ExceptionCallback {
  // Catches a recoverable exception without using try/catch.  Used when compiled with
  // -fno-exceptions.

public:
  virtual ~RecoverableExceptionCatcher() noexcept(false) {}

  void onRecoverableException(Exception&& exception) override {
    if (caught == nullptr) {
      caught = mv(exception);
    } else {
      // TODO(someday):  Consider it a secondary fault?
    }
  }

  Maybe<Exception> caught;
};

Maybe<Exception> runCatchingExceptions(Runnable& runnable) noexcept {
#if KJ_NO_EXCEPTIONS
  RecoverableExceptionCatcher catcher;
  runnable.run();
  KJ_IF_MAYBE(e, catcher.caught) {
    e->truncateCommonTrace();
  }
  return mv(catcher.caught);
#else
  try {
    runnable.run();
    return nullptr;
  } catch (Exception& e) {
    e.truncateCommonTrace();
    return kj::mv(e);
  } catch (std::bad_alloc& e) {
    return Exception(Exception::Type::OVERLOADED,
                     "(unknown)", -1, str("std::bad_alloc: ", e.what()));
  } catch (std::exception& e) {
    return Exception(Exception::Type::FAILED,
                     "(unknown)", -1, str("std::exception: ", e.what()));
  } catch (...) {
    return Exception(Exception::Type::FAILED,
                     "(unknown)", -1, str("Unknown non-KJ exception."));
  }
#endif
}

}  // namespace _ (private)

}  // namespace kj

{'repo_name': 'openai/retro', 'stars': '2128', 'repo_language': 'C', 'file_name': 'gcw0readme.txt', 'mime_type': 'text/plain', 'hash': -9018746685574956758, 'source_dataset': 'data'}


import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

{'repo_name': 'twostraws/Sitrep', 'stars': '705', 'repo_language': 'Swift', 'file_name': 'SitrepTests.swift', 'mime_type': 'text/plain', 'hash': -571782105719984974, 'source_dataset': 'data'}


// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
    if (prev == CodeMirror.Init) prev = false;
    if (prev && !val)
      cm.removeOverlay("trailingspace");
    else if (!prev && val)
      cm.addOverlay({
        token: function(stream) {
          for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
          if (i > stream.pos) { stream.pos = i; return null; }
          stream.pos = l;
          return "trailingspace";
        },
        name: "trailingspace"
      });
  });
});

{'repo_name': 'crmeb/CRMEB', 'stars': '2615', 'repo_language': 'JavaScript', 'file_name': '前端下载地址.md', 'mime_type': 'text/plain', 'hash': -8129682310108420849, 'source_dataset': 'data'}


<!---
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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.
-->

# org.apache.cordova.vibration

Este plugin se alinea con la vibración W3C especificación http://www.w3.org/TR/vibration/

Este plugin proporciona una manera de vibrar el dispositivo.

## Instalación

    cordova plugin add org.apache.cordova.vibration

## Plataformas soportadas

Navigator.Vibrate
Navigator.Notification.Vibrate - Amazon fuego OS - sistema operativo Android - BlackBerry 10 - Firefox - iOS - Windows Phone 7 y 8

navigator.notification.vibrateWithPattern,
navigator.notification.cancelVibration - Android

## vibrar (recomendado)

Esta función tiene tres diferentes funcionalidades basadas en los parámetros pasados a él.

### Estándar de vibrar

Vibra el dispositivo para una cantidad dada de tiempo.

    navigator.vibrate(time)

o

    navigator.vibrate([time])

-**tiempo**: milisegundos a vibrar el dispositivo. *(Número)*

#### Ejemplo

    // Vibrate for 3 seconds
    navigator.vibrate(3000);

    // Vibrate for 3 seconds
    navigator.vibrate([3000]);

#### iOS rarezas

*   **time**: ignora el tiempo especificado y vibra por un tiempo preestablecido.

    navigator.vibrate(3000); // 3000 is ignored

#### Windows y rarezas de Blackberry

*   **tiempo**: tiempo máximo es 5000ms (5s) y min tiempo 1ms

    navigator.vibrate(8000); // will be truncated to 5000

### Vibrar con un patrón (Android y Windows solamente)

Vibra el dispositivo con un patrón determinado

    navigator.vibrate(pattern);

*   **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*

#### Ejemplo

    // Vibrate for 1 second
    // Wait for 1 second
    // Vibrate for 3 seconds
    // Wait for 1 second
    // Vibrate for 5 seconds
    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);

### Cancelar vibración (no soportada en iOS)

Inmediatamente se cancela cualquier vibración actualmente en ejecución.

    navigator.vibrate(0)

o

    navigator.vibrate([])

o

    navigator.vibrate([0])

Pasando en un parámetro de 0, una matriz vacía o una matriz con un elemento de valor 0 se cancelará cualquier vibraciones.

## *Notification.Vibrate (obsoleto)

Vibra el dispositivo para una cantidad dada de tiempo.

    navigator.notification.vibrate(time)

*   **tiempo**: milisegundos a vibrar el dispositivo. *(Número)*

### Ejemplo

    // Vibrate for 2.5 seconds
    navigator.notification.vibrate(2500);

### iOS rarezas

*   **time**: ignora el tiempo especificado y vibra por un tiempo preestablecido.

        navigator.notification.vibrate();
        navigator.notification.vibrate(2500);   // 2500 is ignored

## *Notification.vibrateWithPattern (obsoleto)

Vibra el dispositivo con un patrón determinado.

    navigator.notification.vibrateWithPattern(pattern, repeat)

*   **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*
*   **repito**: índice opcional en la matriz de patrón en el cual comenzar repitiendo (se repite hasta que se cancele), o -1 para la no repetición (por defecto). *(Número)*

### Ejemplo

    // Immediately start vibrating
    // vibrate for 100ms,
    // wait for 100ms,
    // vibrate for 200ms,
    // wait for 100ms,
    // vibrate for 400ms,
    // wait for 100ms,
    // vibrate for 800ms,
    // (do not repeat)
    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);

## *Notification.cancelVibration (obsoleto)

Inmediatamente se cancela cualquier vibración actualmente en ejecución.

    navigator.notification.cancelVibration()

* Nota: debido a la alineación con la especificación del w3c, los métodos favoritos a ser eliminados

{'repo_name': 'blangslet/treasure-hunt', 'stars': '104', 'repo_language': 'Objective-C', 'file_name': 'crossdomain.xml', 'mime_type': 'text/xml', 'hash': 3013374103347810665, 'source_dataset': 'data'}


{'repo_name': 'ares5221/cocos-creator-game', 'stars': '154', 'repo_language': 'JavaScript', 'file_name': 'game-scene.js', 'mime_type': 'text/plain', 'hash': 8723897835901750633, 'source_dataset': 'data'}


/*
 * Copyright 2013 ZXing authors
 *
 * 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.
 */

#import "ZXDataMatrixEncoder.h"

@interface ZXDataMatrixEdifactEncoder : NSObject <ZXDataMatrixEncoder>

@end

{'repo_name': 'januslo/react-native-bluetooth-escpos-printer', 'stars': '136', 'repo_language': 'Objective-C', 'file_name': 'settings.json', 'mime_type': 'text/plain', 'hash': -3779127211328006964, 'source_dataset': 'data'}


#ifndef __ADAU1373_H__
#define __ADAU1373_H__

enum adau1373_pll_src {
	ADAU1373_PLL_SRC_MCLK1 = 0,
	ADAU1373_PLL_SRC_BCLK1 = 1,
	ADAU1373_PLL_SRC_BCLK2 = 2,
	ADAU1373_PLL_SRC_BCLK3 = 3,
	ADAU1373_PLL_SRC_LRCLK1 = 4,
	ADAU1373_PLL_SRC_LRCLK2 = 5,
	ADAU1373_PLL_SRC_LRCLK3 = 6,
	ADAU1373_PLL_SRC_GPIO1 = 7,
	ADAU1373_PLL_SRC_GPIO2 = 8,
	ADAU1373_PLL_SRC_GPIO3 = 9,
	ADAU1373_PLL_SRC_GPIO4 = 10,
	ADAU1373_PLL_SRC_MCLK2 = 11,
};

enum adau1373_pll {
	ADAU1373_PLL1 = 0,
	ADAU1373_PLL2 = 1,
};

enum adau1373_clk_src {
	ADAU1373_CLK_SRC_PLL1 = 0,
	ADAU1373_CLK_SRC_PLL2 = 1,
};

#endif

{'repo_name': 'CyanogenMod/android_kernel_oneplus_msm8974', 'stars': '129', 'repo_language': 'C', 'file_name': 'usb.h', 'mime_type': 'text/x-c', 'hash': 7422501435910657312, 'source_dataset': 'data'}


<?php

/**
 * Theme filters.
 */

namespace App;

/**
 * Add "… Continued" to the excerpt.
 *
 * @return string
 */
add_filter('excerpt_more', function () {
    return ' … ' . __('Continued', 'sage') . '';
});

{'repo_name': 'roots/sage', 'stars': '10720', 'repo_language': 'PHP', 'file_name': 'config.yml', 'mime_type': 'text/plain', 'hash': 5849809257018653063, 'source_dataset': 'data'}


using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using GlobalResources;
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Infrastructure.Exceptions;
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Infrastructure.Models;
using Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.Security;

namespace Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.WebApiControllers
{
    [Authorize]
    [WebApiCSRFValidation]
    public abstract class WebApiControllerBase : ApiController
    {
        protected async Task<HttpResponseMessage> GetServiceResponseAsync(Func<Task> getData)
        {
            if (getData == null)
            {
                throw new ArgumentNullException("getData");
            }

            return await GetServiceResponseAsync<object>(async () =>
            {
                await getData();
                return null;
            });
        }

        /// <summary>
        /// Wraps the response from the getData call into a ServiceResponse object
        /// If an exception is thrown it is caught and put into the Error property of the service response
        /// </summary>
        /// <typeparam name="T">Type returned by the getData call</typeparam>
        /// <param name="getData">Lambda to actually take the action of retrieving the data from the business logic layer</param>
        /// <returns></returns>
        protected async Task<HttpResponseMessage> GetServiceResponseAsync<T>(Func<Task<T>> getData)
        {
            if (getData == null)
            {
                throw new ArgumentNullException("getData");
            }

            return await GetServiceResponseAsync(getData, true);
        }

        /// <summary>
        /// Wraps the response from the getData call into a ServiceResponse object
        /// If an exception is thrown it is caught and put into the Error property of the service response
        /// </summary>
        /// <typeparam name="T">Type returned by the getData call</typeparam>
        /// <param name="getData">Lambda to actually take the action of retrieving the data from the business logic layer</param>
        /// <param name="useServiceResponse">Returns a service response wrapping the data in a Data property in the response, this is ignored if there is an error</param>
        /// <returns></returns>
        protected async Task<HttpResponseMessage> GetServiceResponseAsync<T>(Func<Task<T>> getData, bool useServiceResponse)
        {
            ServiceResponse<T> response = new ServiceResponse<T>();

            if (getData == null)
            {
                throw new ArgumentNullException("getData");
            }

            try
            {
                response.Data = await getData();
            }
            catch (ValidationException ex)
            {
                if (ex.Errors == null || ex.Errors.Count == 0)
                {
                    response.Error.Add(new Error("Unknown validation error"));
                }
                else
                {
                    foreach (string error in ex.Errors)
                    {
                        response.Error.Add(new Error(error));
                    }
                }
            }
            catch (DeviceAdministrationExceptionBase ex)
            {
                response.Error.Add(new Error(ex.Message));
            }
            catch (HttpResponseException)
            {
                throw;
            }
            catch (Exception ex)
            {
                response.Error.Add(new Error(ex));
                Debug.Write(FormatExceptionMessage(ex), " GetServiceResponseAsync Exception");
            }

            // if there's an error or we've been asked to use a service response, then return a service response
            if (response.Error.Count > 0 || useServiceResponse)
            {
                return Request.CreateResponse(
                        response.Error != null && response.Error.Any() ? HttpStatusCode.BadRequest : HttpStatusCode.OK,
                        response);
            }

            // otherwise there's no error and we need to return the data at the root of the response
            return Request.CreateResponse(HttpStatusCode.OK, response.Data);
        }

        protected HttpResponseMessage GetNullRequestErrorResponse<T>()
        {
            ServiceResponse<T> response = new ServiceResponse<T>();
            response.Error.Add(new Error(Strings.RequestNullError));

            return Request.CreateResponse(HttpStatusCode.BadRequest, response);
        }

        protected HttpResponseMessage GetFormatErrorResponse<T>(string parameterName, string type)
        {
            ServiceResponse<T> response = new ServiceResponse<T>();

            string errorMessage =
                String.Format(
                    CultureInfo.CurrentCulture,
                    Strings.RequestFormatError,
                    parameterName, type);

            response.Error.Add(new Error(errorMessage));

            return Request.CreateResponse(HttpStatusCode.BadRequest, response);
        }

        protected void TerminateProcessingWithMessage(HttpStatusCode statusCode, string message)
        {
            HttpResponseMessage responseMessage = new HttpResponseMessage()
            {
                StatusCode = statusCode,
                ReasonPhrase  = message
            };

            throw new HttpResponseException(responseMessage);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.WebApiControllers.WebApiControllerBase.TerminateProcessingWithMessage(System.Net.HttpStatusCode,System.String)")]
        protected void ValidateArgumentNotNullOrWhitespace(string argumentName, string value)
        {
            Debug.Assert(
                !string.IsNullOrWhiteSpace(argumentName),
                "argumentName is a null reference, empty string, or contains only whitespace.");

            if (string.IsNullOrWhiteSpace(value))
            {
                // Error strings are not localized.
                string errorText =
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0} is null, empty, or just whitespace.",
                        argumentName);

                TerminateProcessingWithMessage(HttpStatusCode.BadRequest, errorText);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.WebApiControllers.WebApiControllerBase.TerminateProcessingWithMessage(System.Net.HttpStatusCode,System.String)")]
        protected void ValidateArgumentNotNull(string argumentName, object value)
        {
            Debug.Assert(
                !string.IsNullOrWhiteSpace(argumentName),
                "argumentName is a null reference, empty string, or contains only whitespace.");

            if (value == null)
            {
                // Error strings are not localized.
                string errorText = string.Format(CultureInfo.InvariantCulture, "{0} is a null reference.", argumentName);

                TerminateProcessingWithMessage(HttpStatusCode.BadRequest, errorText);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Azure.Devices.Applications.RemoteMonitoring.DeviceAdmin.Web.WebApiControllers.WebApiControllerBase.TerminateProcessingWithMessage(System.Net.HttpStatusCode,System.String)")]
        protected void ValidatePositiveValue(string argumentName, int value)
        {
            Debug.Assert(
                !string.IsNullOrWhiteSpace(argumentName),
                "argumentName is a null reference, empty string, or contains only whitespace.");

            if (value <= 0)
            {
                // Error strings are not localized.
                string errorText =
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0} is not a positive integer.",
                        argumentName);

                TerminateProcessingWithMessage(HttpStatusCode.BadRequest, errorText);
            }
        }

        private static string FormatExceptionMessage(Exception ex)
        {
            Debug.Assert(ex != null, "ex is a null reference.");

            // Error strings are not localized
            return string.Format(
                CultureInfo.CurrentCulture,
                "{0}{0}*** EXCEPTION ***{0}{0}{1}{0}{0}",
                Console.Out.NewLine,
                ex);
        }
    }
}

{'repo_name': 'Azure/azure-iot-remote-monitoring', 'stars': '254', 'repo_language': 'C#', 'file_name': 'dev-setup.md', 'mime_type': 'text/plain', 'hash': -55160042141248251, 'source_dataset': 'data'}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tibialyzer {
    class TimestampManager {
        public static int createStamp() {
            var time = DateTime.Now;
            int hour = time.Hour;
            int minute = time.Minute;
            return getStamp(hour, minute);

        }

        public static Tuple<int, int> ParseTimestamp(string timestamp) {
            if (timestamp.Length < 5)
                return null;
            return new Tuple<int, int>(int.Parse(timestamp.Substring(0, 2)), int.Parse(timestamp.Substring(3, 2)));
        }

        public static int getStamp(int hour, int minute) { return hour * 60 + minute; }

        public static List<string> getLatestTimes(int count, int ignoreStamp = -1) {
            var time = DateTime.Now;
            int hour = time.Hour;
            int minute = time.Minute;
            return getLatestTimes(hour, minute, count, ignoreStamp);
        }

        public static string FormatTimestamp(int hour, int minute) {
            while (hour < 0) {
                hour += 24;
            }
            while (minute < 0) {
                minute += 60;
            }
            return String.Format("{0:00}:{1:00}", hour, minute);
        }

        public static string getCurrentTimestamp() {
            var time = DateTime.Now;
            int hour = time.Hour;
            int minute = time.Minute;
            return FormatTimestamp(hour, minute);
        }

        public static Tuple<int, int> getCurrentTime() {
            var time = DateTime.Now;
            return new Tuple<int, int>(time.Hour, time.Minute);
        }

        public static List<string> getLatestTimes(int hour, int minute, int count, int ignoreStamp = -1) {
            List<string> stamps = new List<string>();
            for (int i = 0; i < count; i++) {
                if (getStamp(hour, minute) == ignoreStamp) return stamps;

                stamps.Add(FormatTimestamp(hour, minute));

                if (minute == 0) {
                    hour = hour > 0 ? hour - 1 : 23;
                    minute = 59;
                } else {
                    minute = minute - 1;
                }
            }
            return stamps;
        }

        public static List<int> getLatestStamps(int count, int ignoreStamp = -1) {
            var time = DateTime.Now;
            int hour = time.Hour;
            int minute = time.Minute;
            return getLatestStamps(hour, minute, count, ignoreStamp);
        }

        public static List<int> getLatestStamps(int hour, int minute, int count, int ignoreStamp = -1) {
            List<int> stamps = new List<int>();
            for (int i = 0; i < count; i++) {
                int stamp = getStamp(hour, minute);
                stamps.Add(stamp);
                if (stamp == ignoreStamp) return stamps;

                if (minute == 0) {
                    hour = hour > 0 ? hour - 1 : 23;
                    minute = 59;
                } else {
                    minute = minute - 1;
                }
            }
            return stamps;
        }

        public static int getDayStamp() {
            var t = DateTime.Now;
            return t.Year * 400 + t.Month * 40 + t.Day;
        }

        public static int Distance(string timestamp, string timestamp2) {
            var one = ParseTimestamp(timestamp);
            var two = ParseTimestamp(timestamp2);
            return Distance(one.Item1, one.Item2, two.Item1, two.Item2);
        }

        public static int Distance(int hour, int minute, int hour2, int minute2) {
            int v1 = hour * 60 + minute;
            int v2 = hour2 * 60 + minute2;
            return Math.Min(Math.Abs(v2 - v1), Math.Abs((Math.Max(v1, v2) - 60 * 24) - Math.Min(v1, v2)));
        }
    }
}

{'repo_name': 'Mytherin/Tibialyzer', 'stars': '166', 'repo_language': 'C#', 'file_name': 'Resources.Designer.cs', 'mime_type': 'text/plain', 'hash': 7786856797093920791, 'source_dataset': 'data'}


package io.cattle.platform.servicediscovery.service.impl;

import static io.cattle.platform.core.model.tables.AccountLinkTable.*;
import static io.cattle.platform.core.model.tables.RegionTable.*;
import static io.cattle.platform.core.model.tables.ServiceConsumeMapTable.*;
import static io.cattle.platform.core.model.tables.ServiceTable.*;

import io.cattle.platform.agent.instance.dao.AgentInstanceDao;
import io.cattle.platform.core.addon.ExternalCredential;
import io.cattle.platform.core.addon.LbConfig;
import io.cattle.platform.core.addon.PortRule;
import io.cattle.platform.core.constants.AccountConstants;
import io.cattle.platform.core.constants.AgentConstants;
import io.cattle.platform.core.constants.CommonStatesConstants;
import io.cattle.platform.core.constants.CredentialConstants;
import io.cattle.platform.core.constants.InstanceConstants;
import io.cattle.platform.core.constants.ServiceConstants;
import io.cattle.platform.core.model.Account;
import io.cattle.platform.core.model.AccountLink;
import io.cattle.platform.core.model.Agent;
import io.cattle.platform.core.model.Region;
import io.cattle.platform.core.model.Service;
import io.cattle.platform.core.model.ServiceConsumeMap;
import io.cattle.platform.core.util.SystemLabels;
import io.cattle.platform.iaas.api.filter.apikey.ApiKeyFilter;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallbackNoReturn;
import io.cattle.platform.lock.LockManager;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.process.ObjectProcessManager;
import io.cattle.platform.object.process.StandardProcess;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.process.common.lock.AccountLinksUpdateLock;
import io.cattle.platform.servicediscovery.service.RegionService;
import io.cattle.platform.servicediscovery.service.impl.RegionUtil.ExternalAccountLink;
import io.cattle.platform.servicediscovery.service.impl.RegionUtil.ExternalAgent;
import io.cattle.platform.servicediscovery.service.impl.RegionUtil.ExternalProject;
import io.cattle.platform.servicediscovery.service.impl.RegionUtil.ExternalProjectResponse;
import io.cattle.platform.servicediscovery.service.impl.RegionUtil.ExternalRegion;

import io.github.ibuildthecloud.gdapi.condition.Condition;
import io.github.ibuildthecloud.gdapi.condition.ConditionType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RegionServiceImpl implements RegionService {
    private static final Logger log = LoggerFactory.getLogger(RegionServiceImpl.class);
    private static final List<String> INVALID_STATES = Arrays.asList(CommonStatesConstants.REMOVING, CommonStatesConstants.REMOVED);

    @Inject
    ObjectManager objectManager;
    @Inject
    JsonMapper jsonMapper;
    @Inject
    ObjectProcessManager objectProcessManager;
    @Inject
    AgentInstanceDao agentInstanceDao;
    @Inject
    LockManager lockManager;

    @Override
    public void reconcileExternalLinks(long accountId) {
        lockManager.lock(new AccountLinksUpdateLock(accountId),
                new LockCallbackNoReturn() {
                    @Override
                    public void doWithLockNoResult() {
                        List<Region> regions = objectManager.find(Region.class, REGION.REMOVED, new Condition(ConditionType.NULL));
                        if (regions.size() == 0) {
                            return;
                        }
                        Account localAccount = objectManager.loadResource(Account.class, accountId);
                        if (INVALID_STATES.contains(localAccount.getState())) {
                            return;
                        }

                        Map<String, Region> regionsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
                        Region localRegion = null;
                        for (Region region : regions) {
                            regionsMap.put(region.getName(), region);
                            if (region.getLocal()) {
                                localRegion = region;
                            }
                        }

                        List<AccountLink> toRemove = new ArrayList<>();
                        List<AccountLink> toUpdate = new ArrayList<>();
                        Set<String> toCreate = new HashSet<>();

                        fetchAccountLinks(accountId, regionsMap, localRegion, toRemove, toUpdate, toCreate);
                        reconcileAccountLinks(accountId, regionsMap, toRemove, toUpdate, toCreate);
                    }
                });
    }

    private void reconcileAccountLinks(long accountId, Map<String, Region> regionsMap, List<AccountLink> toRemove, List<AccountLink> toUpdate,
            Set<String> toCreate) {
        for (AccountLink item : toRemove) {
            if (!item.getState().equalsIgnoreCase(CommonStatesConstants.REMOVING)) {
                objectProcessManager.scheduleStandardProcess(StandardProcess.REMOVE, item, null);
            }
        }

        Set<String> invalidAccounts = new HashSet<>();

        for (String item : toCreate) {
            String[] splitted = item.split(":");
            String regionName = splitted[0];
            String envName = splitted[1];
            Region region = regionsMap.get(regionName);
            ExternalProject externalProject = null;
            if (region != null && !INVALID_STATES.contains(region.getState())) {
                try {
                    String externalProjectKey = String.format("%s:%s", regionName, envName);
                    if(invalidAccounts.contains(externalProjectKey)) {
                        continue;
                    }
                    ExternalProjectResponse externalProjectResponse = RegionUtil.getTargetProjectByName(region, envName, jsonMapper);
                    externalProject = externalProjectResponse.externalProject;
                    if(externalProject == null) {
                        invalidAccounts.add(externalProjectKey);
                        continue;
                    }
                AccountLink link = objectManager.create(AccountLink.class, ACCOUNT_LINK.ACCOUNT_ID,
                        accountId, ACCOUNT_LINK.LINKED_ACCOUNT, envName, ACCOUNT_LINK.LINKED_REGION, regionName,
                        ACCOUNT_LINK.LINKED_REGION_ID, region.getId(), "linkedAccountUuid", externalProject.getUuid());
                toUpdate.add(link);
                } catch(Exception ex) {
                    log.warn(String.format("Failed to find account for %s - %s", envName, ex));
                }
            }
        }
        for (AccountLink item : toUpdate) {
            if (item.getState().equalsIgnoreCase(CommonStatesConstants.REQUESTED)) {
                objectProcessManager.scheduleStandardProcessAsync(StandardProcess.CREATE, item, null);
            }
        }
    }

    private void fetchAccountLinks(long accountId, Map<String, Region> regionsMap, Region localRegion, List<AccountLink> toRemove, List<AccountLink> toUpdate,
            Set<String> toCreate) {
        List<? extends ServiceConsumeMap> links = objectManager.find(ServiceConsumeMap.class, SERVICE_CONSUME_MAP.ACCOUNT_ID, accountId,
                SERVICE_CONSUME_MAP.REMOVED, null, SERVICE_CONSUME_MAP.CONSUMED_SERVICE, new Condition(ConditionType.NOTNULL));

        Set<String> toAdd = new HashSet<>();
        for (ServiceConsumeMap link : links) {
            if (INVALID_STATES.contains(link.getState())) {
                continue;
            }
            if (link.getConsumedService() == null) {
                continue;
            }
            String[] splitted = link.getConsumedService().split("/");
            if (splitted.length < 3) {
                continue;
            }
            if (splitted.length == 4) {
                if (regionsMap.containsKey(splitted[0])) {
                    toAdd.add(getUUID(splitted[0], splitted[1]));
                }
            } else if (splitted.length == 3) {
                toAdd.add(getUUID(localRegion.getName(), splitted[0]));
            }
        }

        List<? extends Service> lbs = objectManager.find(Service.class, SERVICE.ACCOUNT_ID, accountId,
                SERVICE.REMOVED, null, SERVICE.KIND, ServiceConstants.KIND_LOAD_BALANCER_SERVICE);
        for (Service lb : lbs) {
            if (INVALID_STATES.contains(lb.getState())) {
                continue;
            }
            LbConfig lbConfig = DataAccessor.field(lb, ServiceConstants.FIELD_LB_CONFIG, jsonMapper,
                    LbConfig.class);
            if (lbConfig != null && lbConfig.getPortRules() != null) {
                for (PortRule rule : lbConfig.getPortRules()) {
                    String rName = rule.getRegion();
                    String eName = rule.getEnvironment();
                    if (StringUtils.isEmpty(eName)) {
                        continue;
                    }
                    if (StringUtils.isEmpty(rName)) {
                        rName = localRegion.getName();
                    }
                    if (regionsMap.containsKey(rName)) {
                        toAdd.add(getUUID(rName, eName));
                    }
                }
            }
        }

        List<? extends AccountLink> existingLinks = objectManager.find(AccountLink.class, ACCOUNT_LINK.ACCOUNT_ID, accountId,
                ACCOUNT_LINK.REMOVED, null, ACCOUNT_LINK.LINKED_ACCOUNT, new Condition(ConditionType.NOTNULL), ACCOUNT_LINK.LINKED_REGION,
                new Condition(ConditionType.NOTNULL),
                ACCOUNT_LINK.EXTERNAL, false);
        Set<String> existingLinksKeys = new HashSet<>();
        for (AccountLink existingLink : existingLinks) {
            existingLinksKeys.add(getUUID(existingLink.getLinkedRegion(), existingLink.getLinkedAccount()));
        }

        for (AccountLink link : existingLinks) {
            if (!toAdd.contains(getUUID(link.getLinkedRegion(), link.getLinkedAccount()))) {
                toRemove.add(link);
            } else {
                toUpdate.add(link);
            }
        }
        for (String item : toAdd) {
            if (!existingLinksKeys.contains(item)) {
                toCreate.add(item);
            }
        }
    }

    private String getUUID(String regionName, String envName) {
        return String.format("%s:%s", regionName, envName);
    }

    @Override
    public boolean isRegionsEmpty(Agent agent, Account account, Map<String, Long> externalLinks,  Map<String, ExternalProject> projects,
            Map<Long, Region> regionsIds, Map<String, Region> regionNameToRegion) {
            List<Region> regions = objectManager.find(Region.class, REGION.REMOVED, (Object) null);
            for(Region region : regions) {
                regionsIds.put(region.getId(), region);
                regionNameToRegion.put(region.getName(), region);
            }

        getLinkedEnvironments(account.getId(), externalLinks, regionsIds, projects);

        boolean noExternalLinks = externalLinks.isEmpty();
        List<? extends ExternalCredential> existing = DataAccessor.fieldObjectList(agent, AccountConstants.FIELD_EXTERNAL_CREDENTIALS, ExternalCredential.class,
                jsonMapper);
        boolean noExternalCreds = existing.isEmpty();
        if (noExternalLinks && noExternalCreds) {
            return true;
        }

            return false;
    }

    @Override
    public boolean reconcileAgentExternalCredentials(Agent agent, Account account, Map<String, Long> externalLinks, Map<String, ExternalProject> projects,
            Map<Long, Region> regionsIds, Map<String, Region> regionNameToRegion) {
        Region localRegion = null;

        for (Region region : regionsIds.values()) {
            if (region.getLocal()) {
                localRegion = region;
            }
        }
        boolean success = true;

        // 2. Reconcile agent's credentials
        try {
            reconcileExternalCredentials(account, agent, localRegion, externalLinks, projects, regionNameToRegion);
        } catch (Exception ex) {
            success = false;
            log.error(String.format("Fail to reconcile credentials for agent [%d]", agent.getId()), ex);
        }
        return success;
    }

    protected void reconcileExternalCredentials(Account account, Agent agent, Region localRegion, Map<String, Long> externalLinks,
            Map<String, ExternalProject> externalProjects, Map<String, Region> regionNameToRegion) {

        // 1. Set credentials
        Map<String, ExternalCredential> toAdd = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        Map<String, ExternalCredential> toRemove = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        Map<String, ExternalCredential> toRetain = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        setCredentials(agent, externalLinks, toAdd, toRemove, toRetain);

        // 2. Reconcile agents
        reconcileExternalAgents(account, agent, localRegion, regionNameToRegion, toAdd, toRemove, toRetain, externalProjects);
    }

    private ExternalAgent createExternalAgent(Agent agent, Account account, Region localRegion, Region targetRegion,
            ExternalCredential cred, Map<String, ExternalProject> externalProjects) {
        // Create external agent with local credentials
        try {
            String UUID = getUUID(targetRegion.getName(), cred.getEnvironmentName());
            ExternalProject targetResourceAccount = null;
            if (externalProjects.containsKey(UUID)) {
                targetResourceAccount = externalProjects.get(UUID);
            } else {
                    ExternalProjectResponse externalProjectResponse = RegionUtil.getTargetProjectByName(targetRegion, cred.getEnvironmentName(), jsonMapper);
                targetResourceAccount = externalProjectResponse.externalProject;
                if (targetResourceAccount == null) {
                    throw new RuntimeException(String.format("Failed to find target environment by name [%s] in region [%s]",
                            cred.getEnvironmentName(), targetRegion.getName()));
                }
                externalProjects.put(UUID, targetResourceAccount);
            }

            String targetAgentUri = RegionUtil.getTargetAgentUri(localRegion.getName(), account.getName(), agent.getUuid(), targetResourceAccount.getUuid());
            log.info(String.format("Creating external agent with uri [%s] in environment [%s] in region [%s]",
                    targetAgentUri,
                    cred.getEnvironmentName(),
                    cred.getRegionName()));
            Map<String, Object> data = new HashMap<>();
            data.put(AgentConstants.DATA_AGENT_RESOURCES_ACCOUNT_ID, targetResourceAccount.getId());
            data.put(CredentialConstants.PUBLIC_VALUE, cred.getPublicValue());
            data.put(CredentialConstants.SECRET_VALUE, cred.getSecretValue());
            data.put(AgentConstants.FIELD_URI, targetAgentUri);
            data.put(AgentConstants.FIELD_EXTERNAL_ID, agent.getUuid());
            Map<String, String> labels = new HashMap<>();
            labels.put(SystemLabels.LABEL_AGENT_SERVICE_METADATA, "true");
            data.put(InstanceConstants.FIELD_LABELS, labels);
            data.put("activateOnCreate", true);
            return RegionUtil.createExternalAgent(targetRegion, cred.getEnvironmentName(), data, jsonMapper);
        } catch (Exception e) {
            log.error("Failed to create external agent", e);
            return null;
        }
    }

    @Override
    /**
     * This method creates an external account link in the target environment as ipsec service
     * would need two way links
     */
    public void createExternalAccountLink(AccountLink link) {
        if (link.getExternal()) {
            return;
        }
        try {
            Region targetRegion = objectManager.loadResource(Region.class, link.getLinkedRegionId());
            Region localRegion = objectManager.findAny(Region.class, REGION.LOCAL, true, REGION.REMOVED, null);
            if(localRegion == null) {
                    log.warn("No local region present");
                    return;
            }
            ExternalRegion externalRegion = RegionUtil.getExternalRegion(targetRegion, localRegion.getName(), jsonMapper);
            if (externalRegion == null) {
                throw new RuntimeException(String.format("Failed to find local region [%s] in external region [%s]",
                        localRegion.getName(), targetRegion.getName()));
            }
            ExternalProjectResponse externalProjectResponse = RegionUtil.getTargetProjectByName(targetRegion, link.getLinkedAccount(), jsonMapper);
            ExternalProject targetResourceAccount = externalProjectResponse.externalProject;
            if (targetResourceAccount == null) {
                throw new RuntimeException(String.format("Failed to find target environment by name [%s] in region [%s]",
                        link.getLinkedAccount(), localRegion.getName()));
            }
            Account localAccount = objectManager.loadResource(Account.class, link.getAccountId());
            ExternalAccountLink externalLink = RegionUtil.getExternalAccountLink(targetRegion,
                    targetResourceAccount, localAccount, jsonMapper);
            if (externalLink != null) {
                return;
            }

            Map<String, Object> data = new HashMap<>();
            data.put("accountId", targetResourceAccount.getId());
            data.put("external", "true");
            data.put("linkedAccount", localAccount.getName());
            data.put("linkedRegion", externalRegion.getName());
            data.put("linkedRegionId", externalRegion.getId());
            data.put("linkedAccountUuid", localAccount.getUuid());
            externalLink = RegionUtil.createExternalAccountLink(targetRegion, data, jsonMapper);
        } catch (Exception ex) {
            throw new RuntimeException(String.format("Failed to create external account link for accountLink [%d]", link.getId()), ex);
        }
    }

    @Override
    public boolean deleteExternalAccountLink(AccountLink link) {
        if (link.getExternal()) {
            return true;
        }
        try {
            Region targetRegion = objectManager.loadResource(Region.class, link.getLinkedRegionId());
            if(targetRegion == null) {
                return true;
            }
            ExternalProjectResponse externalProjectResponse = RegionUtil.getTargetProjectByName(targetRegion, link.getLinkedAccount(), jsonMapper);
            ExternalProject targetResourceAccount = externalProjectResponse.externalProject;
            if (targetResourceAccount == null) {
                String UUID = DataAccessor.fieldString(link, "linkedAccountUuid");
                targetResourceAccount = RegionUtil.getTargetProjectByUUID(targetRegion, UUID, jsonMapper);
                if (targetResourceAccount == null) {
                    log.info(String.format("Failed to find target environment by UUID [%s] in region [%s]",
                            UUID, targetRegion.getName()));
                    return true;
                }
            }
            Account localAccount = objectManager.loadResource(Account.class, link.getAccountId());
            ExternalAccountLink externalLink = RegionUtil.getExternalAccountLink(targetRegion, targetResourceAccount,
                    localAccount, jsonMapper);
            if (externalLink == null) {
                return true;
            }
            RegionUtil.deleteExternalAccountLink(targetRegion, externalLink);
            return true;
        } catch (Exception ex) {
                log.error(String.format("Failed to delete external account link for accountLink [%d]", link.getId()), ex);
                return false;
        }
    }

    private void reconcileExternalAgents(Account account, Agent agent,
            Region localRegion,
            Map<String, Region> regions,
            Map<String, ExternalCredential> toAdd,
            Map<String, ExternalCredential> toRemove,
            Map<String, ExternalCredential> toRetain,
            Map<String, ExternalProject> externalProjects) {

        // 1. Add missing agents
        boolean changed = false;
        for (String key : toAdd.keySet()) {
            ExternalCredential value = toAdd.get(key);
            ExternalAgent externalAgent = createExternalAgent(agent, account, localRegion, regions.get(value.getRegionName()), toAdd.get(key),
                    externalProjects);
            if (externalAgent != null) {
                value.setAgentUuid(externalAgent.getUuid());
                // only add credential of the agent which got created successfully
                toRetain.put(key, value);
                changed = true;
            }
        }

        // 2. Remove extra agents.
        for (String key : toRemove.keySet()) {
            ExternalCredential value = toRemove.get(key);
            deactivateAndRemoveExternalAgent(agent, value);
            changed = true;
        }
        if (changed) {
            objectManager.setFields(agent, AccountConstants.FIELD_EXTERNAL_CREDENTIALS, toRetain.values());
        }
    }

    protected boolean deactivateAndRemoveExternalAgent(Agent agent, ExternalCredential cred) {
        Region targetRegion = objectManager.loadResource(Region.class, cred.getRegionId());
        if (targetRegion == null) {
            log.info(String.format("Failed to find target region by name [%s]", cred.getRegionName()));
            return true;
        }

        String regionName = cred.getRegionName();
        String envName = cred.getEnvironmentName();
        try {
            log.info(String.format("Removing agent with externalId [%s] in environment [%s] and region [%s]", agent.getUuid(), regionName,
                    envName));
            ExternalAgent externalAgent = RegionUtil.getExternalAgent(targetRegion, cred.getAgentUuid(), jsonMapper);
            if (externalAgent == null) {
                log.info(String.format("Failed to find agent by externalId [%s] in environment [%s] and region [%s]", agent.getUuid(), regionName,
                        envName));
                return true;
            }
            RegionUtil.deleteExternalAgent(agent, targetRegion, externalAgent);
            return true;
        } catch (Exception e) {
            log.error(
                    String.format("Failed to deactivate agent with externalId [%s] in environment [%s] and region [%s]", agent.getUuid(), regionName, envName),
                    e);
            return false;
        }
    }

    private void setCredentials(Agent agent, Map<String, Long> externalLinks,
            Map<String, ExternalCredential> toAdd, Map<String, ExternalCredential> toRemove, Map<String, ExternalCredential> toRetain) {
        List<? extends ExternalCredential> existing = DataAccessor.fieldObjectList(agent, AccountConstants.FIELD_EXTERNAL_CREDENTIALS, ExternalCredential.class,
                jsonMapper);

        Map<String, ExternalCredential> existingCredentials = new HashMap<>();
        for (ExternalCredential cred : existing) {
            existingCredentials.put(getUUID(cred.getRegionName(), cred.getEnvironmentName()), cred);
        }

        for (String key : externalLinks.keySet()) {
            String[] splitted = key.split(":");
            String regionName = splitted[0];
            String envName = splitted[1];
            String uuid = getUUID(regionName, envName);
            if (existingCredentials.containsKey(uuid)) {
                toRetain.put(uuid, existingCredentials.get(uuid));
            } else {
                String[] keys = ApiKeyFilter.generateKeys();
                toAdd.put(uuid, new ExternalCredential(envName, regionName, keys[0], keys[1], externalLinks.get(key)));
            }
        }

        for (String key : existingCredentials.keySet()) {
            if (!(toAdd.containsKey(key) || toRetain.containsKey(key))) {
                toRemove.put(key, existingCredentials.get(key));
            }
        }
    }

    private void getLinkedEnvironments(long accountId, Map<String, Long> links, Map<Long, Region> regionsIds,
            Map<String, ExternalProject> externalProjects) {
        List<AccountLink> accountLinks = objectManager.find(AccountLink.class, ACCOUNT_LINK.ACCOUNT_ID,
                accountId, ACCOUNT_LINK.REMOVED, null, ACCOUNT_LINK.LINKED_REGION_ID, new Condition(ConditionType.NOTNULL));

        for (AccountLink link : accountLinks) {
                if (link.getState().equalsIgnoreCase(CommonStatesConstants.REMOVING)) {
                    continue;
                }
                if(link.getState().equalsIgnoreCase(CommonStatesConstants.REMOVED)) {
                    continue;
                }
            Region targetRegion = regionsIds.get(link.getLinkedRegionId());
            if (targetRegion == null) {
                continue;
            }
            String UUID = getUUID(targetRegion.getName(), link.getLinkedAccount());
            if (!externalProjects.containsKey(UUID)) {
                links.put(UUID, targetRegion.getId());
            }
        }
    }

    @Override
    public boolean deactivateAndRemoveExternalAgent(Agent agent) {
        List<? extends ExternalCredential> creds = DataAccessor.fieldObjectList(agent, AccountConstants.FIELD_EXTERNAL_CREDENTIALS, ExternalCredential.class,
                jsonMapper);
        if (creds.isEmpty()) {
            return true;
        }

        Map<String, Region> regions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        for (Region region : objectManager.find(Region.class, REGION.REMOVED, new Condition(ConditionType.NULL))) {
            regions.put(region.getName(), region);
        }
        for (ExternalCredential cred : creds) {
            if (!deactivateAndRemoveExternalAgent(agent, cred)) {
                return false;
            }
        }
        return true;
    }
}

{'repo_name': 'rancher/cattle', 'stars': '557', 'repo_language': 'Java', 'file_name': 'key.pem', 'mime_type': 'text/plain', 'hash': -3147716183969784083, 'source_dataset': 'data'}


/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */

package java.util;

/**
 * The {@code TimerTask} class represents a task to run at a specified time. The task
 * may be run once or repeatedly.
 *
 * @see Timer
 * @see java.lang.Object#wait(long)
 */
public abstract class TimerTask implements Runnable {
    /* Lock object for synchronization. It's also used by Timer class. */
    final Object lock = new Object();

    /* If timer was cancelled */
    boolean cancelled;

    /* Slots used by Timer */
    long when;

    long period;

    boolean fixedRate;

    /*
     * The time when task will be executed, or the time when task was launched
     * if this is task in progress.
     */
    private long scheduledTime;

    /*
     * Method called from the Timer for synchronized getting of when field.
     */
    long getWhen() {
        synchronized (lock) {
            return when;
        }
    }

    /*
     * Method called from the Timer object when scheduling an event @param time
     */
    void setScheduledTime(long time) {
        synchronized (lock) {
            scheduledTime = time;
        }
    }

    /*
     * Is TimerTask scheduled into any timer?
     *
     * @return {@code true} if the timer task is scheduled, {@code false}
     * otherwise.
     */
    boolean isScheduled() {
        synchronized (lock) {
            return when > 0 || scheduledTime > 0;
        }
    }

    /**
     * Creates a new {@code TimerTask}.
     */
    protected TimerTask() {
        super();
    }

    /**
     * Cancels the {@code TimerTask} and removes it from the {@code Timer}'s queue. Generally, it
     * returns {@code false} if the call did not prevent a {@code TimerTask} from running at
     * least once. Subsequent calls have no effect.
     *
     * @return {@code true} if the call prevented a scheduled execution
     *         from taking place, {@code false} otherwise.
     */
    public boolean cancel() {
        synchronized (lock) {
            boolean willRun = !cancelled && when > 0;
            cancelled = true;
            return willRun;
        }
    }

    /**
     * Returns the scheduled execution time. If the task execution is in
     * progress it returns the execution time of the ongoing task. Tasks which
     * have not yet run return an undefined value.
     *
     * @return the most recent execution time.
     */
    public long scheduledExecutionTime() {
        synchronized (lock) {
            return scheduledTime;
        }
    }

    /**
     * The task to run should be specified in the implementation of the {@code run()}
     * method.
     */
    public abstract void run();

}

{'repo_name': 'openweave/openweave-core', 'stars': '172', 'repo_language': 'C++', 'file_name': 'missing-space-after-else-if.cmp', 'mime_type': 'text/plain', 'hash': 8729209115718349387, 'source_dataset': 'data'}


typedef float tocheck_t;
#define ESIZE 8
#define MSIZE 23
#define FUNC(x) x##f

#include "test-arith.c"

{'repo_name': 'bminor/glibc', 'stars': '400', 'repo_language': 'C', 'file_name': 'check_fds.c', 'mime_type': 'text/x-c', 'hash': -8404801540995662651, 'source_dataset': 'data'}


var nativeCreate = require('./_nativeCreate');

/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/**
 * Sets the hash `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Hash
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the hash instance.
 */
function hashSet(key, value) {
  var data = this.__data__;
  this.size += this.has(key) ? 0 : 1;
  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  return this;
}

module.exports = hashSet;

{'repo_name': 'ZhuPeng/mp-githubtrending', 'stars': '163', 'repo_language': 'JavaScript', 'file_name': 'HISTORY.md', 'mime_type': 'text/plain', 'hash': -3955121372658426389, 'source_dataset': 'data'}


/*----------------------------------------------------------------
    Copyright (C) 2020 Senparc

    文件名：EncryptResponseMessage.cs
    文件功能描述：返回给服务器的加密消息

    创建标识：Senparc - 20150313

    修改标识：Senparc - 20150313
    修改描述：整理接口
----------------------------------------------------------------*/

namespace Senparc.Weixin.Work.Entities.Response
{
    /// <summary>
    /// 返回给服务器的加密消息
    /// </summary>
    public class EncryptResponseMessage
    {
        public string Encrypt { get; set; }
        public string MsgSignature { get; set; }
        public string TimeStamp { get; set; }
        public string Nonce { get; set; }
    }
}

{'repo_name': 'JeffreySu/WeiXinMPSDK', 'stars': '6300', 'repo_language': 'C#', 'file_name': 'readme.md', 'mime_type': 'text/plain', 'hash': 732963491761181724, 'source_dataset': 'data'}


object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 577
  ClientWidth = 351
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnClose = FormClose
  OnShow = FormShow
  DesignerMasterStyle = 1
  object Panel1: TPanel
    Align = Client
    Size.Width = 351.000000000000000000
    Size.Height = 577.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 12
    object TabControl1: TTabControl
      Align = Client
      FullSize = True
      Size.Width = 351.000000000000000000
      Size.Height = 577.000000000000000000
      Size.PlatformDefault = False
      TabHeight = 49.000000000000000000
      TabIndex = 0
      TabOrder = 1
      TabPosition = Bottom
      object TabItem1: TTabItem
        CustomIcon = <
          item
          end>
        IsSelected = True
        Size.Width = 176.000000000000000000
        Size.Height = 49.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        Text = 'Bluetooth settings'
        object ButtonDiscover: TButton
          Position.X = 4.000000000000000000
          Position.Y = 59.000000000000000000
          Size.Width = 158.000000000000000000
          Size.Height = 31.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          Text = 'Discover devices'
          OnClick = ButtonDiscoverClick
        end
        object ButtonPair: TButton
          Position.X = 183.000000000000000000
          Position.Y = 59.000000000000000000
          Size.Width = 78.000000000000000000
          Size.Height = 31.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
          Text = 'Pair'
          OnClick = ButtonPairClick
        end
        object ButtonPairedDevices: TButton
          Position.X = 4.000000000000000000
          Position.Y = 140.000000000000000000
          Size.Width = 158.000000000000000000
          Size.Height = 31.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 2
          Text = 'Paired Devices'
          OnClick = ButtonPairedDevicesClick
        end
        object ButtonUnPair: TButton
          Position.X = 269.000000000000000000
          Position.Y = 59.000000000000000000
          Size.Width = 80.000000000000000000
          Size.Height = 31.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 3
          Text = 'UnPair'
          OnClick = ButtonUnPairClick
        end
        object ComboBoxDevices: TComboBox
          Position.X = 4.000000000000000000
          Position.Y = 92.000000000000000000
          Size.Width = 352.000000000000000000
          Size.Height = 32.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 4
        end
        object ComboBoxPaired: TComboBox
          Position.X = 4.000000000000000000
          Position.Y = 173.000000000000000000
          Size.Width = 352.000000000000000000
          Size.Height = 32.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 5
          OnChange = ComboBoxPairedChange
        end
        object ButtonServices: TButton
          Position.X = 4.000000000000000000
          Position.Y = 221.000000000000000000
          Size.Width = 158.000000000000000000
          Size.Height = 31.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 6
          Text = 'Services'
          OnClick = ButtonServicesClick
        end
        object ComboBoxServices: TComboBox
          Position.X = 4.000000000000000000
          Position.Y = 254.000000000000000000
          Size.Width = 352.000000000000000000
          Size.Height = 32.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 7
        end
      end
      object TabItem2: TTabItem
        CustomIcon = <
          item
          end>
        IsSelected = False
        Size.Width = 175.000000000000000000
        Size.Height = 49.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        Text = 'Service demo'
        object PanelClient: TPanel
          Position.Y = 134.000000000000000000
          Size.Width = 360.000000000000000000
          Size.Height = 153.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          object Button2: TButton
            Position.X = 4.000000000000000000
            Position.Y = 115.000000000000000000
            Size.Width = 73.000000000000000000
            Size.Height = 25.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 0
            Text = 'Clear'
            OnClick = Button2Click
          end
          object Edit1: TEdit
            Touch.InteractiveGestures = [LongTap, DoubleTap]
            TabOrder = 1
            Text = 'I am the text sent'
            Position.X = 4.000000000000000000
            Position.Y = 71.000000000000000000
            Size.Width = 343.000000000000000000
            Size.Height = 32.000000000000000000
            Size.PlatformDefault = False
          end
          object FreeSocket: TButton
            Position.X = 190.000000000000000000
            Position.Y = 115.000000000000000000
            Size.Width = 157.000000000000000000
            Size.Height = 25.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 2
            Text = 'Free Client Socket'
            OnClick = FreeSocketClick
          end
          object LabelNameServer: TLabel
            Position.X = 157.000000000000000000
            Position.Y = 22.000000000000000000
            Size.Width = 180.000000000000000000
            Size.Height = 40.000000000000000000
            Size.PlatformDefault = False
          end
          object LabelClient: TLabel
            StyledSettings = [Family, Size, FontColor]
            Position.X = 4.000000000000000000
            Size.Width = 227.000000000000000000
            Size.Height = 20.000000000000000000
            Size.PlatformDefault = False
            Text = 'Client'
          end
          object ButtonConnectToRFCOMM: TButton
            Position.X = 4.000000000000000000
            Position.Y = 28.000000000000000000
            Size.Width = 143.000000000000000000
            Size.Height = 33.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 5
            Text = 'Send text to ->'
            OnClick = ButtonConnectToRFCOMMClick
          end
        end
        object PanelServer: TPanel
          Position.Y = 40.000000000000000000
          Size.Width = 360.000000000000000000
          Size.Height = 93.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
          object ButtonCloseReadingSocket: TButton
            Position.X = 195.000000000000000000
            Position.Y = 32.000000000000000000
            Size.Width = 160.000000000000000000
            Size.Height = 36.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 0
            Text = 'Remove text service'
            OnClick = ButtonCloseReadingSocketClick
          end
          object ButtonOpenReadingSocket: TButton
            Position.X = 4.000000000000000000
            Position.Y = 32.000000000000000000
            Size.Width = 160.000000000000000000
            Size.Height = 36.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 1
            Text = 'Create text service'
            OnClick = ButtonOpenReadingSocketClick
          end
          object LabelServer: TLabel
            StyledSettings = [Family, Size, FontColor]
            Position.X = 4.000000000000000000
            Size.Width = 227.000000000000000000
            Size.Height = 20.000000000000000000
            Size.PlatformDefault = False
            Text = 'Server'
          end
        end
      end
    end
    object Labeldiscoverable: TLabel
      StyledSettings = [Family, Style, FontColor]
      Position.X = 16.000000000000000000
      Position.Y = 8.000000000000000000
      Size.Width = 321.000000000000000000
      Size.Height = 23.000000000000000000
      Size.PlatformDefault = False
    end
    object DisplayR: TMemo
      Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
      Anchors = [akLeft, akTop, akRight]
      Position.Y = 288.000000000000000000
      Size.Width = 351.000000000000000000
      Size.Height = 232.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 2
      TabStop = False
      ReadOnly = True
      ShowSizeGrip = True
    end
  end
end

{'repo_name': 'FMXExpress/Firemonkey', 'stars': '137', 'repo_language': 'Pascal', 'file_name': 'ExplorerDevicesLECppPCH1.h', 'mime_type': 'text/x-c', 'hash': -6401851681079547426, 'source_dataset': 'data'}


<?php

/*
 * @copyright   2019 Mautic Contributors. All rights reserved
 * @author      Mautic
 *
 * @link        https://mautic.org
 *
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 */

namespace Mautic\CoreBundle\Form\Type;

use Mautic\LeadBundle\Helper\FormFieldHelper;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RegionType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            [
                'choices'           => FormFieldHelper::getRegionChoices(),
                'choice_value'      => function ($state) {
                    return $state;
                },
                'label_attr'        => ['class' => 'control-label'],
                'attr'              => ['class' => 'form-control'],
                'multiple'          => false,
                'expanded'          => false,
            ]
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return ChoiceType::class;
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'region';
    }
}

{'repo_name': 'mautic/mautic', 'stars': '3970', 'repo_language': 'PHP', 'file_name': 'ButtonSubscriber.php', 'mime_type': 'text/x-php', 'hash': -7191621999943724651, 'source_dataset': 'data'}


#ifndef CONFIG_CPPTOC_H
#define CONFIG_CPPTOC_H

#include "cpptoc.h"
#include "sinet_capi.h"
#include "../sinet/config.h"

class config_cpptoc:
  public cpptoc<config_cpptoc, config, _config_t>
{
public:
  config_cpptoc(config* cls);
  virtual ~config_cpptoc(void){}
};

#endif // CONFIG_CPPTOC_H

{'repo_name': 'tomasen/splayer', 'stars': '819', 'repo_language': 'C++', 'file_name': 'install_test.bat', 'mime_type': 'text/plain', 'hash': 3918085609644763827, 'source_dataset': 'data'}