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

#include <fcntl.h>
#include <fuchsia/crash/cpp/fidl.h>
#include <fuchsia/net/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fsl/vmo/file.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/logger.h>
#include <stdlib.h>
#include <zircon/errors.h>
#include <zircon/status.h>

#include <string>

#include "src/lib/files/file.h"
#include "src/lib/files/unique_fd.h"
#include "src/lib/fxl/logging.h"

class CrashAnalyzer {
 public:
  CrashAnalyzer() : context_(sys::ComponentContext::Create()) {
    FXL_DCHECK(context_);
  }

  void ProcessCrashlog(fuchsia::mem::Buffer crashlog) {
    fuchsia::crash::AnalyzerSyncPtr analyzer;
    context_->svc()->Connect(analyzer.NewRequest());
    FXL_DCHECK(analyzer);

    fuchsia::crash::Analyzer_OnKernelPanicCrashLog_Result out_result;
    const zx_status_t status =
        analyzer->OnKernelPanicCrashLog(std::move(crashlog), &out_result);
    if (status != ZX_OK) {
      FX_LOGS(ERROR) << "failed to connect to crash analyzer: " << status
                     << " (" << zx_status_get_string(status) << ")";
    } else if (out_result.is_err()) {
      FX_LOGS(ERROR) << "failed to process kernel panic crash log: "
                     << out_result.err() << " ("
                     << zx_status_get_string(out_result.err()) << ")";
    }
  }

 private:
  std::unique_ptr<sys::ComponentContext> context_;
};

int main(int argc, char** argv) {
  syslog::InitLogger({"crash"});

  const char filepath[] = "/boot/log/last-panic.txt";
  fxl::UniqueFD fd(open(filepath, O_RDONLY));
  if (!fd.is_valid()) {
    FX_LOGS(INFO) << "no kernel crash log found";
    return EXIT_SUCCESS;
  }

  fsl::SizedVmo crashlog_vmo;
  if (!fsl::VmoFromFd(std::move(fd), &crashlog_vmo)) {
    FX_LOGS(ERROR) << "error loading kernel crash log into VMO";
    return EXIT_FAILURE;
  }

  std::string crashlog_str;
  if (!fsl::StringFromVmo(crashlog_vmo, &crashlog_str)) {
    FX_LOGS(ERROR) << "error converting kernel crash log VMO to string";
    return EXIT_FAILURE;
  }
  FX_LOGS(INFO) << "dumping log from previous kernel panic:\n" << crashlog_str;

  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  fuchsia::net::ConnectivityPtr connectivity =
      sys::ComponentContext::Create()
          ->svc()
          ->Connect<fuchsia::net::Connectivity>();
  connectivity.events().OnNetworkReachable = [&crashlog_vmo](bool reachable) {
    if (!reachable) {
      return;
    }
    CrashAnalyzer crash_analyzer;
    crash_analyzer.ProcessCrashlog(std::move(crashlog_vmo).ToTransport());
  };
  loop.Run();

  return EXIT_SUCCESS;
}
