edition = "2023";

option go_package = "codeberg.org/git-pages/git-pages/git_pages";

import "google/protobuf/timestamp.proto";

enum Type {
	// Invalid entry.
	InvalidEntry = 0;
	// Directory.
	Directory = 1;
	// Inline file. `Blob.Data` contains file contents.
	InlineFile = 2;
	// External file. `Blob.Data` contains object reference.
	ExternalFile = 3;
	// Symlink. `Blob.Data` contains relative path.
	Symlink = 4;
}

// Transformation names should match HTTP `Accept-Encoding:` header.
enum Transform {
	// No transformation.
	Identity = 0;
	// Zstandard compression.
	Zstd = 1;
}

message Entry {
	Type type = 1;
	// Only present for `type == InlineFile` and `type == ExternalFile`.
	// For transformed entries, refers to the pre-transformation (decompressed) size; otherwise
	// equal to `compressed_size`.
	int64 original_size = 7;
	// Only present for `type == InlineFile` and `type == ExternalFile`.
	// For transformed entries, refers to the post-transformation (compressed) size; otherwise
	// equal to `original_size`.
	int64 compressed_size = 2;
	// Meaning depends on `type`:
	//  * If `type == InlineFile`, contains file data.
	//  * If `type == ExternalFile`, contains blob name (an otherwise unspecified
	//    cryptographically secure content hash).
	//  * If `type == Symlink`, contains link target.
	//  * Otherwise not present.
	bytes data = 3;
	// Only present for `type == InlineFile` and `type == ExternalFile` that
	// have been transformed.
	Transform transform = 4;
	// Only present for `type == InlineFile` and `type == ExternalFile`.
	// Currently, optional (not present on certain legacy manifests).
	string content_type = 5;
	// May be present for `type == InlineFile` and `type == ExternalFile`.
	// Used to reduce the amount of work being done during git checkouts.
	// The type of hash used is determined by the length:
	//   * 40 bytes: SHA1DC (as hex)
	//   * 64 bytes: SHA256 (as hex)
	string git_hash = 6;
}

// See https://docs.netlify.com/manage/routing/redirects/overview/ for details.
// Only a subset of the Netlify specification is representable here.
message RedirectRule {
	string from = 1;
	string to = 2;
	uint32 status = 3;
	bool force = 4;
}

// See https://docs.netlify.com/manage/routing/headers/ for details.
message Header {
	string name = 1;
	repeated string values = 2;
}

message HeaderRule {
	string path = 1;
	repeated Header header_map = 2;
}

message Problem {
	string path = 1;
	string cause = 2;
}

message Manifest {
	// Source metadata.
	string repo_url = 1;
	string branch = 2;
	string commit = 3;

	// Site contents.
	map<string, Entry> contents = 4;
	int64 original_size = 10; // sum of each `entry.original_size`
	int64 compressed_size = 5; // sum of each `entry.compressed_size`
	int64 stored_size = 8; // sum of deduplicated `entry.compressed_size` for external files only

	// Netlify-style `_redirects` and `_headers` rules.
	repeated RedirectRule redirects = 6;
	repeated HeaderRule headers = 9;

	// Diagnostics for non-fatal errors.
	repeated Problem problems = 7;
}

enum AuditEvent {
	// Invalid event.
	InvalidEvent = 0;
	// A manifest was committed (a site was created or updated).
	CommitManifest = 1;
	// A manifest was deleted (a site was deleted).
	DeleteManifest = 2;
	// A domain was frozen.
	FreezeDomain = 3;
	// A domain was thawed.
	UnfreezeDomain = 4;
}

message AuditRecord {
	// Audit event metadata.
	int64 id = 1;
	google.protobuf.Timestamp timestamp = 2;
	AuditEvent event = 3;
	Principal principal = 4;

	// Affected resource.
	string domain = 10;
	string project = 11; // only for `*Manifest` events

	// Snapshot of site manifest.
	Manifest manifest = 12;  // only for `*Manifest` events
}

message Principal {
	string ip_address = 1;
	bool cli_admin = 2;
}
