// Copyright 2017 The Fuchsia 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.
syntax = "proto3";

package cobalt.analyzer;

import "analyzer/report_master/report_master.proto";
import "config/report_configs.proto";

/////////////////////////////////////////////////////////////////////////////
// This file contains report-related proto messages that are used internally
// by the Cobalt Analyzer but are not part of the public ReportMaster API.
/////////////////////////////////////////////////////////////////////////////

// The unique identifier for an instance of a report. In the public API we
// hide the complexity of a ReportId message and use an opaque string as the
// type of a |report_id|. But that string is actually the Base64 encoding of
// the serialization of a ReportId.
message ReportId {
  // (customer_id, project_id, report_config_id) together specify which
  // ReportConfig this is a report for.
  uint32 customer_id = 1;
  uint32 project_id= 2;
  uint32 report_config_id= 3;

  // A report is an instance of the class of all reports that share a
  // ReportConfig. The instance_id uniquely represents this report instance.
  // It is randomly generated.
  uint32 instance_id = 4;

  // The time, in seconds since the Unix epoch, that the metadata for this
  // report was created in the ReportStore. The |start_time| (recorded in the
  // ReportMetadataLite) may be later than this if the report started off
  // in the WAITING_TO_START state.
  int64 creation_time_seconds = 5;

  // This field serves to distinguish the different reports within a
  // dependency group of reports. All reports within the group share all
  // other fields of ReportId. The first report within the group to be started
  // has sequence_num 0.
  uint32 sequence_num = 6;
}

// Metadata about an instance of a report. This is the internal version
// of this structure that is stored in the ReportStore. The version
// of ReportMetadata in the public API in report_master.proto contains
// additional fields that may be derived from the ReportId and must be
// populated when a ReportMetadata is returned to a user.
message ReportMetadataLite {
  // The current state of the report generation.
  ReportState state = 1;

  // The time that the generation of this report began, as recorded by the
  // server, in seconds since the Unix epoch.
  int64 start_time_seconds = 2;

  // The time that the generation of this report completed, as recorded by the
  // server, in seconds since the Unix epoch. This is unset if the report
  // processing is not completed.
  int64 finish_time_seconds = 3;

  // This report analyzes Observations with a day_index in the range
  // [first_day_index, last_day_index]
  uint32 first_day_index = 4;
  uint32 last_day_index = 5;

  // The type of report that this is. This may be different from the type
  // of report specified in the ReportConfig if this report is an auxilliary
  // report automatically generated by the system in support of the primary
  // report. For example if the primary report type is JOINT this report may
  // be one of the automatically generated one-way marginal reports in which
  // case its type would be  HISTOGRAM.
  ReportType report_type = 6;

  // The ReportConfig specifies a list of variables to be analyzed in the
  // report. This report may be an auxiallary report automatically generated
  // by the system in support of the primary report. In this field we record
  // which of the variables specified in the ReportConfig are analyzed by
  // this report. For example if the primary report is a JOINT report and this
  // report is one of the one-way marginal reports then this field will contain
  // a single value that will be 0 for the first one-way marginal and 1 for
  // the second one-way marginal.
  repeated uint32 variable_indices = 7;

  // Is this a one-off report that was explicitly requested via the
  // StartReport method as opposed to being generated by regular periodic
  // report scheduling? This is purely for informational purposes and has no
  // other bearing on the report.
  bool one_off = 8;

  // Any human-readable messages directed toward the report consumer that
  // were produced by the server during the generation of the report.
  repeated InfoMessage info_messages = 9;
}
