// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <fuchsia/crash/cpp/fidl.h>
#include <fuchsia/net/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fdio/util.h>
#include <lib/fidl/cpp/synchronous_interface_ptr.h>
#include <lib/fsl/vmo/file.h>
#include <lib/fsl/vmo/strings.h>
#include <lib/fxl/files/file.h>
#include <lib/fxl/files/unique_fd.h>
#include <lib/fxl/logging.h>
#include <lib/syslog/cpp/logger.h>
#include <lib/zx/vmo.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

class CrashAnalyzer {
 public:
  explicit CrashAnalyzer()
      : context_(component::StartupContext::CreateFromStartupInfo()) {
    FXL_DCHECK(context_);
  }

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

    zx_status_t out_status;
    const zx_status_t status =
        analyzer->ProcessKernelPanicCrashlog(std::move(crashlog), &out_status);
    if (status != ZX_OK) {
      FX_LOGS(ERROR) << "failed to connect to crash analyzer: " << status
                     << " (" << zx_status_get_string(status) << ")";
    } else if (out_status != ZX_OK) {
      FX_LOGS(ERROR) << "failed to process kernel panic crash log: "
                     << out_status << " (" << zx_status_get_string(out_status)
                     << ")";
    }
  }

 private:
  std::unique_ptr<component::StartupContext> 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 0;
  }

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

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

  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  fuchsia::net::ConnectivityPtr connectivity =
      component::StartupContext::CreateFromStartupInfo()
          ->ConnectToEnvironmentService<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 0;
}
