# Copyright (c) 2022 Firebuild Inc.
# All rights reserved.
# Free for personal use and commercial trial.
# Non-trial commercial use requires licenses available from https://firebuild.com.
# Modification and redistribution are permitted, but commercial use of
# derivative works is subject to the same requirements of this license
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# This is the definition of the FBB format used for fingerprinting a
# process.

# This is a Python dictionary, to be read and processed by "generate_fbb".

{
  "types_with_custom_debugger": ["mode_t", "firebuild::fd_type", "XXH128_hash_t"],

  "extra_c": """
    /* Debugger method for mode_t fields. */
    static void fbbfp_debug_mode_t(FILE *f, mode_t mode) {
      fprintf(f, "\\"");
      debug_mode_t(f, mode);
      fprintf(f, "\\"");
    }

    /* Debugger method for firebuild::fd_type fields. */
    static void fbbfp_debug_firebuild__fd_type(FILE *f, firebuild::fd_type type) {
      fprintf(f, "\\"%s\\"", fd_type_to_string(type));
    }

    /* Debugger method for XXH128_hash_t fields. */
    static void fbbfp_debug_XXH128_hash_t(FILE *f, XXH128_hash_t value) {
      firebuild::Hash hash(value);
      char ascii[firebuild::Hash::kAsciiLength + 1];
      hash.to_ascii(ascii);
      fprintf(f, "\\"%s\\"", ascii);
    }
  """,

  "extra_h": """
    #include <xxhash.h>
    #include "firebuild/file_fd.h"
    #include "firebuild/hash.h"
    #include "common/debug_sysflags.h"
  """,

  "tags": [
    ("file", [
      # file path, absolute or relative
      (REQUIRED, STRING,          "path"),
      # checksum (binary) of the file content, empty if file is not found
      (REQUIRED, "XXH128_hash_t", "hash"),
      # TODO add alternate hash values generated after preprocessing the file
      # with programs keeping the semantic content (e.g. removing white spaces)
      #(REQUIRED, "XXH128_hash_t", "alt_hash"),

      # last modification time - FIXME in what unit?
      #(OPTIONAL, "long",          "mtime"),
      # file size, length in case of stdio
      #(OPTIONAL, "size_t",        "size"),
      # TODO refine mode
      (OPTIONAL, "mode_t",        "mode"),
      # The reason why the file could not be opened.
      #(OPTIONAL, "int",           "error_no"),
    ]),

    # Represents an inherited open file description, along with the fds
    ("ofd", [
      # Type
      (REQUIRED, "firebuild::fd_type", "type"),
      # Client-side fds pointing to the same open file description, in
      # ascending order
      (ARRAY, "int", "fds"),

      # FIXME fcntl flags?
      # FIXME seek positions?
    ]),

    # Properties of a process that are known when it starts up, and are
    # expected to be the same across identical launches. These take a key
    # part in deciding whether it can be shortcutted. This includes command
    # line flags, selected environment variables and such. Things that are
    # expected to change across runs, e.g. pid, ppid, $FB_SOCKET etc. are
    # not included here. Things that only become known while the process is
    # running, such as the files it reads, aren't included either.
    ("process_fingerprint", [
      (REQUIRED, "int",  "kFingerprintVersion"),
      (ARRAY,    STRING, "ignore_locations"),
      # The initial umask
      (REQUIRED, "mode_t", "umask"),
      # The initial working directory
      (REQUIRED, STRING, "wd"),
      # Program file
      (REQUIRED, FBB,    "executable"),      # tag "file"
      # Pathname used to execute the program in absolute and canonical form
      (REQUIRED, FBB,    "executed_path"),   # tag "file"
      # Original pathname used to execute the program
      (REQUIRED, STRING, "original_executed_path"),   # tag "file"
      # Command parameters, starting with name of the command
      (ARRAY,    STRING, "args"),
      (OPTIONAL, "XXH128_hash_t", "param_file_hash"),
      # Environment variables, filtered (to exclude e.g. $FB_SOCKET)
      # and sorted to a deterministic order
      (ARRAY,    STRING, "env"),
      # Libraries loaded upon startup
      (ARRAY,    FBB,    "libs"),            # tag "file"
      # An entry for each inherited open file description, in ascending
      # order of their lowest fd
      (ARRAY,    FBB,    "ofds"),            # tag "ofd"
    ]),
  ]
}
