// Copyright 2021 Google LLC
//
// 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
//
//     https://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 = "proto2";

package org.datacommons.proto;

import "google/protobuf/timestamp.proto";
import "LogLocation.proto";
import "Mcf.proto";

//
// Runtime metadata capturing when and how the report was generated.
// This information is used to track report generation context including
// timestamp, input files, and tool version - essential for reviewing
// old imports where reports may be obsolete or need validation.
//
message RuntimeMetadata {
    reserved 1, 2;  // start_time_millis and end_time_millis removed in favor of Timestamp fields
    optional string username = 3;
    optional string hostname = 4;
    optional string os_name = 5;
    optional string os_version = 6;
    optional string java_version = 7;
    optional string tool_version = 8;  // From pom.xml or Main.java
    optional string tool_build_timestamp = 9;  // Build time if available
    optional string tool_git_commit_hash = 10;  // Git commit if available
    optional google.protobuf.Timestamp start_time = 11;  // Start time as protobuf Timestamp
    optional google.protobuf.Timestamp end_time = 12;  // End time as protobuf Timestamp
}

//
// A log of import processing with details on any warnings, errors, etc.
//
message Log {

    // Severity level of the message.
    enum Level {
        LEVEL_UNSPECIFIED = 0;
        LEVEL_INFO = 1;
        LEVEL_WARNING = 2;
        LEVEL_ERROR = 3;
        LEVEL_FATAL = 4;
    }

    message CounterSet {
      // Key is the name of a counter.
      map<string, int64> counters = 1;
    }

    // One log entry. This could be a sample of messages for a particular
    // counter.
    message Entry {
        optional Level level = 1;
        optional Location location = 2;
        // This must be user understandable.
        optional string user_message = 3;
        // A counter key in CounterSet.
        optional string counter_key = 4;

        // Column names set when the error corresponds to a column in the CSV.
        // The row info is in "location".
        // TODO: Set this by plumbing it into McfParser.parseTypedValue().
        repeated string column_name = 5;
    }

    // Key: Level.name()
    map<string, CounterSet> level_summary = 1;
    repeated Entry entries = 3;
    repeated StatValidationResult stats_check_summary = 4;
    optional CommandArgs command_args = 5;
    optional RuntimeMetadata runtime_metadata = 6;
    reserved 2;
}

message CommandArgs {
    enum ResolutionMode {
        RESOLUTION_MODE_UNSPECIFIED = 0;
        // No resolution necessary.
        RESOLUTION_MODE_NONE = 1;
        // Perform local-ID resolution and DCID generation, but no external-ID resolution.
        // This involves no DC Recon API calls.
        RESOLUTION_MODE_LOCAL = 2;
        // Perform local-ID resolution, external-ID resolution and DCID generation.
        RESOLUTION_MODE_FULL = 3;
    }
    optional bool existence_checks = 1;
    optional ResolutionMode resolution = 2;
    optional int32 num_threads = 3;
    optional bool stat_checks = 4;
    repeated string sample_places = 5;
    optional bool observation_about = 6;
    optional bool allow_nan_svobs = 7;  // allow not-a-number svobs values
    // check the existence of SVObs value references if the SV they are measuring has statType: measurementResult
    optional bool check_measurement_result = 8;
    optional bool coordinates_resolution = 9;
    optional bool include_runtime_metadata = 10;
    repeated string input_files = 11;  // List of input file paths
    optional string delimiter = 12;    // CSV delimiter character
}

message DataPoint {
    message DataValue {
        optional McfGraph.TypedValue value = 1;
        // The location in the file where this value was read from.
        repeated Location locations = 2;
    }

    optional string date = 1;
    // Multiple values for a single date only happens when there's a bug.
    repeated DataValue values = 2;
}

message StatValidationResult {
    // DCID of the place.
    optional string place_dcid = 1;
    // DCID of the stat var.
    optional string stat_var_dcid = 2;
    // Additional information that characterizes the time series that this
    // StatValidationResult is validating.
    optional string measurement_method = 3;
    optional string observation_period = 4;
    optional string scaling_factor = 5;
    optional string unit = 6;

    // Information about a single stat validation check that failed.
    message StatValidationEntry {
        // Key that describes the failed validation check.
        optional string counter_key = 1;
        // DataPoints that caused this validation error.
        repeated DataPoint problem_points = 2;
        // Additional details as a message that is user understandable.
        optional string additional_details = 3;
        // Only set for percent fluctuation counters.
        optional double percent_difference = 4;
    }

    repeated StatValidationEntry validation_counters = 7;
}
