// Copyright 2017 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.

#ifndef COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "analyzer/report_master/report_internal.pb.h"
#include "analyzer/report_master/report_row_iterator.h"
#include "analyzer/report_master/report_stream.h"
#include "config/report_configs.pb.h"
#include "grpc++/grpc++.h"
#include "util/gcs/gcs_util.h"

namespace cobalt {
namespace analyzer {

// An abstract interface for uploading serialized reports to Google Cloud
// Storage. This allows us to mock out the upload step in unit tests.
class GcsUploadInterface {
 public:
  virtual ~GcsUploadInterface() = default;
  virtual grpc::Status UploadToGCS(const std::string& bucket,
                                   const std::string& path,
                                   const std::string& mime_type,
                                   ReportStream* report_stream) = 0;
};

// An implementation of GcsUploadInterface that actually uploads files to
// Google Cloud Storage.
class GcsUploader : public GcsUploadInterface {
 public:
  virtual ~GcsUploader() = default;

  grpc::Status UploadToGCS(const std::string& bucket, const std::string& path,
                           const std::string& mime_type,
                           ReportStream* report_stream) override;

 private:
  grpc::Status PingBucket(const std::string& bucket);

  std::unique_ptr<util::gcs::GcsUtil> gcs_util_;
};

// A ReportExporter is used by the ReportMaster to export serialized reports
// to external systems.
//
// Usage:
// Construct an instance of ReportExporter passing in an instance of
// GcsUploadInterface. In production this should be an instance of
// GcsUploader but in a test this may be a mock. This instance may
// live for the lifetime of the program, but it is not thread-safe.
// Invoke ExportReport() repeatedly.
class ReportExporter {
 public:
  // Constructs an instance of ReportExporter that will use |uploader| for
  // uploading to Google Cloud Storage.
  explicit ReportExporter(std::shared_ptr<GcsUploadInterface> uploader);

  // Serializes and exports the provided report to an external system, or else
  // immediately returns grpc::OK, based on the data in the provided parameters,
  // as described below.
  //
  // report_config: The ExportConfigs from here determine how to serialize the
  // report (for example to a CSV file) and the locations of where to export
  // the report (for example to a Google Cloud Storage bucket.)  In the case of
  // exporting to Google Cloud Storage, the ExportConfig specifies a bucket and
  // a folder path, but not the file name. That is taken from the |export_name|
  // field of |metadata|. If the |export_name| field of |metadata| is not set
  // then no exporting will be done and this method will immediately return
  // grpc::OK.
  //
  // There may be any number of ExportConfigs. If there are zero ExportConfigs
  // then no exporting will be done and this method will immediately
  // return grpc::OK. If there are one or more ExportConfigs then the
  // report will be exported to one or more locations and grpc::OK will be
  // returned just in case all of the exports are successful.
  //
  // Also, the metric part names within the ReportVariables are taken from
  // |report_config| and used as the column headers for the value columns of
  // the serialized report. Note that the |report_type| is not taken from here
  // but rather from |metadata|. This is because the report being serialized may
  // be an auxilliary report rather than the primary report for the
  // ReportConfig.
  //
  // metadata. As described previously, if the |export_name| field
  // from here is empty then no exporting will be done and this method will
  // immediately return grpc::OK. Otherwise the |export_name| field specifes
  // part of the location of where to export the file.
  //
  // Also the |report_type| is taken from |metadata|. Also the list of
  // |variable_indices| from here determines which ReportVariables from
  // |report_config| are used, and their order.
  //
  // row_iterator: An iterator that will yield the actual row data to be
  // serialized and exported. The type of the rows must correspond to the
  // |report_type| from |metadata|.
  //
  // Returns grpc::OK if either no exporter was done, or if all exporting
  // was successful. Otherwise logs an error and returns some other status.
  grpc::Status ExportReport(const ReportConfig& report_config,
                            const ReportMetadataLite& metadata,
                            ReportRowIterator* row_iterator);

 private:
  friend class ReportExporterTest;

  std::shared_ptr<GcsUploadInterface> uploader_;

  grpc::Status ExportReportOnce(const ReportConfig& report_config,
                                const ReportMetadataLite& metadata,
                                const ReportExportConfig& export_config,
                                ReportRowIterator* row_iterator);

  grpc::Status ExportReportToGCS(const ReportConfig& report_config,
                                 const GCSExportLocation& location,
                                 const ReportMetadataLite& metadata,
                                 const std::string& mime_type,
                                 ReportStream* report_stream);

  // Builds a file path for exporting to Google Cloud Storage by concatenating
  // a folder path based on the report config id, the metadata export_name,
  // and a dot extension based on the mime type.
  static std::string GcsPath(const ReportConfig& report_config,
                             const ReportMetadataLite& metadata,
                             const std::string& mime_type);
};

}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_REPORT_MASTER_REPORT_EXPORTER_H_
