syntax = "proto3";

message Metadata {
    // this format is versioned
    int32 version = 1;
    // git hash of the revision from which Hercules is built
    string hash = 2;
    // repository's name
    string repository = 3;
    // UNIX timestamp of the first analysed commit
    int64 begin_unix_time = 4;
    // UNIX timestamp of the last analysed commit
    int64 end_unix_time = 5;
    // number of processed commits
    int32 commits = 6;
    // duration of the analysis in milliseconds
    int64 run_time = 7;
    // time taken by each pipeline item in seconds
    map<string, double> run_time_per_item = 8;
}

message BurndownSparseMatrixRow {
    // the first `len(column)` elements are stored,
    // the rest `number_of_columns - len(column)` values are zeros
    repeated uint32 columns = 1;
}

message BurndownSparseMatrix {
    string name = 1;
    int32 number_of_rows = 2;
    int32 number_of_columns = 3;
    // `len(row)` matches `number_of_rows`
    repeated BurndownSparseMatrixRow rows = 4;
}

message BurndownAnalysisResults {
    // how many days are in each band [burndown_project, burndown_file, burndown_developer]
    int32 granularity = 1;
    // how frequently we measure the state of each band [burndown_project, burndown_file, burndown_developer]
    int32 sampling = 2;
    // always exists
    BurndownSparseMatrix project = 3;
    // this is included if `-burndown-files` was specified
    repeated BurndownSparseMatrix files = 4;
    // these two are included if `-burndown-people` was specified
    repeated BurndownSparseMatrix people = 5;
    // rows and cols order correspond to `burndown_developer`
    CompressedSparseRowMatrix people_interaction = 6;
}

message CompressedSparseRowMatrix {
    int32 number_of_rows = 1;
    int32 number_of_columns = 2;
    // https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR.2C_CRS_or_Yale_format.29
    repeated int64 data = 3;
    repeated int32 indices = 4;
    repeated int64 indptr = 5;
}

message Couples {
    // name of each `matrix`'s row and column
    repeated string index = 1;
    // is always square
    CompressedSparseRowMatrix matrix = 2;
}

message TouchedFiles {
    repeated int32 files = 1;  // values correspond to `file_couples::index`
}

message CouplesAnalysisResults {
    Couples file_couples = 6;
    Couples people_couples = 7;
    // order corresponds to `people_couples::index`
    repeated TouchedFiles people_files = 8;
}

message UASTChange {
    string file_name = 1;
    string src_before = 2;
	string src_after = 3;
	string uast_before = 4;
	string uast_after = 5;
}

message UASTChangesSaverResults {
    repeated UASTChange changes = 1;
}

message ShotnessRecord {
    string internal_role = 1;
    repeated int32 roles = 2;
    string name = 3;
    string file = 4;
    map<int32, int32> counters = 5;
}

message ShotnessAnalysisResults {
    repeated ShotnessRecord records = 1;
}

message FileHistory {
    repeated string commits = 1;
}

message FileHistoryResultMessage {
    map<string, FileHistory> files = 1;
}

message DevDay {
    int32 commits = 1;
    int32 added = 2;
    int32 removed = 3;
    int32 changed = 4;
}

message DayDevs {
    map<int32, DevDay> devs = 1;
}

message DevsAnalysisResults {
    map<int32, DayDevs> days = 1;
    repeated string dev_index = 2;
}

message Sentiment {
    float value = 1;
    repeated string comments = 2;
    repeated string commits = 3;
}

message CommentSentimentResults {
    map<int32, Sentiment> sentiment_by_day = 1;
}

message AnalysisResults {
    Metadata header = 1;
    // the mapped values are dynamic messages which require the second parsing pass.
    map<string, bytes> contents = 2;
}
