// Copyright 2019 The Chromium OS 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 <sysexits.h>

#include <fstream>
#include <iostream>

#include <base/optional.h>
#include <brillo/flag_helper.h>
#include <brillo/http/http_request.h>
#include <brillo/http/http_transport.h>
#include <chromeos/libipp/ipp.h>

#include "print_tools/ipp_in_json.h"

namespace {

// Help message about the application.
constexpr char app_info[] =
    "This tool tries to send IPP "
    "Get-Printer-Attributes request to given URL and parse obtained "
    "response. If no output files are specified, the obtained response "
    "is printed to stdout as formatted JSON";

// Prints information about HTTP error to stderr.
void PrintHttpError(const std::string& msg, const brillo::ErrorPtr* err_ptr) {
  std::cerr << "Error occured at HTTP level: " << msg << "\n";
  if (err_ptr != nullptr && err_ptr->get() != nullptr) {
    std::cerr << "Reported errors stack:\n";
    for (const brillo::Error* error = err_ptr->get(); error != nullptr;
         error = error->GetInnerError()) {
      std::cerr << error->GetDomain() << ":";
      std::cerr << error->GetCode() << ":";
      std::cerr << error->GetLocation().file_name() << ",";
      std::cerr << error->GetLocation().function_name() << ",";
      std::cerr << error->GetLocation().line_number() << ":";
      std::cerr << error->GetMessage() << "\n";
    }
  }
  std::cerr << std::flush;
}

// Sends IPP frame (in |data| parameter) to given URL. In case of error, it
// prints out error message to stderr and returns nullopt. Otherwise, it returns
// the body from the response.
base::Optional<std::vector<uint8_t>> SendIppFrameAndGetResponse(
    std::string url, const std::vector<uint8_t>& data) {
  using Transport = brillo::http::Transport;
  using Request = brillo::http::Request;
  using Response = brillo::http::Response;
  // Replace ipp/ipps protocol in the given URL to http/https.
  if (url.substr(0, 6) == "ipp://") {
    url = "http" + url.substr(3);
  } else if (url.substr(0, 7) == "ipps://") {
    url = "https" + url.substr(4);
  }
  // Prepare HTTP request.
  std::shared_ptr<Transport> transport = Transport::CreateDefault();
  transport->UseCustomCertificate(Transport::Certificate::kNss);
  Request request(url, "POST", transport);
  request.SetContentType("application/ipp");
  brillo::ErrorPtr error;
  if (!data.empty()) {
    if (!request.AddRequestBody(data.data(), data.size(), &error)) {
      PrintHttpError("cannot set request body", &error);
      return base::nullopt;
    }
  }
  // Send the request and interpret obtained response.
  std::unique_ptr<Response> response = request.GetResponseAndBlock(&error);
  if (response == nullptr) {
    PrintHttpError("exchange failed", &error);
    return base::nullopt;
  }
  if (!response->IsSuccessful()) {
    const std::string msg = "unexpected response code: " +
                            std::to_string(response->GetStatusCode());
    PrintHttpError(msg, &error);
    return base::nullopt;
  }
  return (response->ExtractData());
}

// Write the content of given buffer to given filename ("location"). When
// "location" equals "-", the content is written to stdout. In case of an error,
// it prints out error message to stderr and returns false. The "buffer"
// parameter cannot be nullptr, exactly "size" elements is read from it.
bool WriteBufferToLocation(const char* buffer,
                           unsigned size,
                           const std::string& location) {
  if (location == "-") {
    std::cout.write(buffer, size);
    std::cout << std::endl;
    if (std::cout.bad()) {
      std::cerr << "Error when writing results to standard output.\n";
      return false;
    }
  } else {
    std::ofstream file(location, std::ios::binary | std::ios::trunc);
    if (!file.good()) {
      std::cerr << "Error when opening the file " << location << ".\n";
      return false;
    }
    file.write(buffer, size);
    file.close();
    if (file.bad()) {
      std::cerr << "Error when writing to the file " << location << ".\n";
      return false;
    }
  }
  return true;
}

}  // namespace

// Return codes:
// * EX_USAGE or EX_DATAERR: incorrect command line parameters
// * -1: cannot build IPP request (libipp error)
// * -2: HTTP exchange error (brillo/http or HTTP error)
// * -3: cannot save an output to given file (I/O error?)
// * -4: cannot build JSON output (base/json error).
// * -5: cannot parse IPP response (incorrect frame was received)
int main(int argc, char** argv) {
  // Define and parse command line parameters, exit if incorrect.
  DEFINE_string(url, "", "Address to query");
  DEFINE_string(version, "1.1", "IPP version (default 1.1)");
  DEFINE_string(
      jsonf, "",
      "Save the response as formatted JSON to given file (use - for stdout)");
  DEFINE_string(
      jsonc, "",
      "Save the response as compressed JSON to given file (use - for stdout)");
  DEFINE_string(
      binary, "",
      "Dump the response to given file as a binary content (use - for stdout)");
  brillo::FlagHelper::Init(argc, argv, app_info);
  // Parse the IPP version.
  ipp::Version version;
  if (!ipp::FromString(FLAGS_version, &version)) {
    std::cerr << "Unknown version: " << FLAGS_version << ". ";
    std::cerr << "Allowed values: 1.0, 1.1, 2.0, 2.1, 2.2." << std::endl;
    return EX_USAGE;
  }
  // If no output files were specified, set the default settings.
  if (FLAGS_binary.empty() && FLAGS_jsonc.empty() && FLAGS_jsonf.empty())
    FLAGS_jsonf = "-";

  // Send IPP request and get a response.
  ipp::Request_Get_Printer_Attributes request;
  request.operation_attributes->printer_uri.Set(FLAGS_url);
  ipp::Client client(version);
  client.BuildRequestFrom(&request);
  std::vector<uint8_t> data;
  if (!client.WriteRequestFrameTo(&data)) {
    std::cerr << "Error when preparing frame with IPP request." << std::endl;
    return -1;
  }
  auto data_optional = SendIppFrameAndGetResponse(FLAGS_url, data);
  if (!data_optional)
    return -2;
  data = std::move(*data_optional);
  // Write raw frame to file if needed.
  if (!FLAGS_binary.empty()) {
    if (!WriteBufferToLocation(reinterpret_cast<const char*>(data.data()),
                               data.size(), FLAGS_binary)) {
      return -3;
    }
  }

  // Parse the IPP response and save results.
  int return_code = 0;
  ipp::Response_Get_Printer_Attributes response;
  if (client.ReadResponseFrameFrom(data) &&
      client.ParseResponseAndSaveTo(&response)) {
    std::cerr << "Parsing of an obtained response was not completed."
              << std::endl;
    return_code = -5;
    // Let's continue, we can still return some data (it is not our error).
  }
  if (!FLAGS_jsonc.empty()) {
    std::string json;
    if (!ConvertToJson(response, client.GetErrorLog(), true, &json)) {
      std::cerr << "Error when preparing a report in JSON (compressed)."
                << std::endl;
      return -4;
    }
    if (!WriteBufferToLocation(json.data(), json.size(), FLAGS_jsonc)) {
      return -3;
    }
  }
  if (!FLAGS_jsonf.empty()) {
    std::string json;
    if (!ConvertToJson(response, client.GetErrorLog(), false, &json)) {
      std::cerr << "Error when preparing a report in JSON (formatted)."
                << std::endl;
      return -4;
    }
    if (!WriteBufferToLocation(json.data(), json.size(), FLAGS_jsonf)) {
      return -3;
    }
  }

  return return_code;
}
