// Copyright 2018 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
//
//      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";
option go_package = "github.com/google/fswalker";

package fswalker;

import "google/protobuf/timestamp.proto";

// Reviews is a collection of "known good" states, one per host.
// It is used to keep the default to compare newer reports against.
message Reviews {
  map<string, Review> review = 1;  // Keyed by the FQDN of the host.
}

message Review {
  // The ID of the Walk that was reviewed and considered ok.
  // This will become the last known good.
  string walk_id = 1;
  // Reference to the Walk source (e.g. absolute path).
  string walk_reference = 2;
  // Mandatory fingerprint of the walk file (to ensure integrity).
  Fingerprint fingerprint = 3;
}

message ReportConfig {
  // version is the version of the proto structure.
  uint32 version = 1;

  // exclude_pfx is a list of path prefixes which will be excluded from being
  // reported. Note that these are prefixes. Any path matching one of these
  // prefixes will be ignored. These are in addition to the exclusions in the
  // client policy so more things can be recorded (but ignored in the default
  // report).
  repeated string exclude_pfx = 2;
}

message Policy {
  // version is the version of the proto structure.
  uint32 version = 1;

  // include is a list of paths to use as roots for file walks.
  // Each walk can be done by a separate Go routine (if an idle one is
  // available). Important to note that the include paths SHOULD NOT contain
  // each other because that will lead to paths being visited more than once.
  repeated string include = 2;

  // exclude_pfx is a list of path prefixes which will be excluded from being
  // walked. Note that these are prefixes. Any path matching one of these
  // prefixes will be ignored.
  repeated string exclude_pfx = 3;

  // hash_pfx is a list of path prefixes. If the discovered File path is not a
  // directory, matches one of the prefixes and is not larger than
  // max_hash_file_size, the file will be opened and a file hash built over its
  // content.
  repeated string hash_pfx = 4;
  int64 max_hash_file_size = 5;

  // Flags to control general behavior of Walker.

  // walk_cross_device controls whether files on different devices from the
  // include directories should be walked. I.e. if "/" is included, "/tmp" will
  // only be walked if it is not a separate mount point.
  bool walk_cross_device = 30;
  // ignore_irregular_files controls whether irregular files (i.e. symlinks,
  // sockets, devices, etc) should be ignored.
  // Note that symlinks are NOT followed either way.
  bool ignore_irregular_files = 31;
  // max_directory_depth controls how many levels of directories Walker should
  // walk into an included directory.
  // Defaults to no restriction on depth (i.e. go all the way).
  uint32 max_directory_depth = 32;
}

message Walk {
  // A unique string identifying this specific Walk.
  string id = 1;
  // version is the version of the proto structure.
  uint32 version = 2;
  // policy is the Policy that was used for the file walk.
  Policy policy = 3;
  // file is a list of all files including metadata that were discovered.
  repeated File file = 4;
  // notification is a list of notifications that occurred during a walk.
  repeated Notification notification = 5;

  // hostname of the machine the walk originates from.
  string hostname = 10;
  // start and stop time of the walk.
  google.protobuf.Timestamp start_walk = 11;
  google.protobuf.Timestamp stop_walk = 12;
}

message Notification {
  // Indicator for the severity of the notification.
  enum Severity {
    UNKNOWN = 0;
    INFO    = 1;
    WARNING = 2;
    ERROR   = 3;
  }
  Severity severity = 1;
  // path where the notification occurred.
  string path = 2;
  // human readable message.
  string message = 3;
}

//
// The comparison logic might need to be updated if anything below changes.
//

message FileInfo {
  // base name of the file
  string name = 1;
  // length in bytes for regular files; system-dependent for others
  int64 size = 2;
  // file mode bits
  uint32 mode = 3;
  // modification time
  google.protobuf.Timestamp modified = 4;
  // abbreviation for Mode().IsDir()
  bool is_dir = 5;
}

message FileStat {
  uint64 dev = 1;
  uint64 inode = 2;
  uint64 nlink = 3;

  uint32 mode = 4;
  uint32 uid = 5;
  uint32 gid = 6;

  uint64 rdev = 7;
  int64 size = 8;
  int64 blksize = 9;
  int64 blocks = 10;

  google.protobuf.Timestamp atime = 11;
  google.protobuf.Timestamp mtime = 12;
  google.protobuf.Timestamp ctime = 13;
}

// Fingerprint is a unique identifier for a given File.
// It consists of a Method (e.g. SHA256) and a value.
message Fingerprint {
  enum Method {
    UNKNOWN = 0;
    SHA256  = 1;
  }
  Method method = 1;
  string value = 2;
}

message File {
  // version is the version of the proto structure.
  uint32 version = 1;

  // path is the full file path including the file name.
  string path = 2;

  FileInfo info = 3;
  FileStat stat = 4;

  // fingerprint is optionally set when requested for the specific file.
  repeated Fingerprint fingerprint = 5;
}
