// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

syntax = "proto2";
option optimize_for = LITE_RUNTIME;
option java_package = "org.chromium.components.optimization_guide.proto";
option java_outer_classname = "HintsProto";

package optimization_guide.proto;

import "common_types.proto";
import "loading_predictor_metadata.proto";
import "performance_hints_metadata.proto";
import "previews_metadata.proto";
import "public_image_metadata.proto";

// Information about the hint that the client already has for a host.
message MatchedHintInfo {
  // Describes the granularity of the key field.
  optional KeyRepresentation key_representation = 1;
  // The key of the hint currently used for the host.
  optional string key = 2;
  // The version of the hint for this key already stored on the client.
  optional int64 version = 3;
}

message HostInfo {
  // Host that the client is requesting information for.
  optional string host = 1;
  // Information about the hint that the client already has for the host.
  optional MatchedHintInfo matched_hint = 2;
}

// Information about a URL to request hints for.
message UrlInfo {
  // The URL that the client is requesting information for.
  optional string url = 1;
}

// Request to return a set of hints that guide what optimizations to perform
// on those hosts.
message GetHintsRequest {
  // Information about the set of hosts to retrieve hints for.
  repeated HostInfo hosts = 1;

  // Information about the set of URLs to retrieve hints for.
  repeated UrlInfo urls = 4;

  // The set of optimization types that the requesting client can support
  // and perform.
  //
  // It is guaranteed that the response will only contain hints for
  // optimizations present in this set.
  repeated OptimizationType supported_optimizations = 2;

  // Context in which this request is made.
  optional RequestContext context = 3;
}

// Response to the GetHints request.
message GetHintsResponse {
  // An ordered list containing hints for key/optimization combinations.
  //
  // It is guaranteed that there will only be a single hint per key and key
  // representation combination. These hints are intended to apply to a full
  // page. It is expected that the client will use the Hint record with the
  // most specific key that matches the main frame URL.
  //
  // Note, this list may contain multiple hints that apply to a page. For
  // example, if there are hints for (HOST_SUFFIX,cnn.com) and
  // (HOST_SUFFIX,sports.cnn.com), these may both apply to
  // sports.cnn.com/foo. In this case, the client is expected to use the
  // hints from (HOST_SUFFIX,sports.cnn.com).
  repeated Hint hints = 1;

  // The maximum duration in which the hints, or lack of hints, provided in
  // this response are valid.
  optional Duration max_cache_duration = 2;

  // A set of hint keys to remove from the client cache.
  //
  // It is guaranteed that all entries in this list were provided by the client
  // in the corresponding request's |hosts.matched_hint| fields.
  //
  // It is expected for the client to immediately stop using all hints contained
  // in this field. Hints that are not present in |hints| or in this field
  // should adhere to the client cache's existing expiration policy.
  repeated MatchedHintInfo hints_to_remove = 3;
}

// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
// This is local definition matching server side duration.proto definition.
message Duration {
  // Signed seconds of the span of time. Must be from -315,576,000,000
  // to +315,576,000,000 inclusive.
  optional int64 seconds = 1;

  // Signed fractions of a second at nanosecond resolution of the span
  // of time. Durations less than one second are represented with a 0
  // `seconds` field and a positive or negative `nanos` field. For durations
  // of one second or more, a non-zero value for the `nanos` field must be
  // of the same sign as the `seconds` field. Must be from -999,999,999
  // to +999,999,999 inclusive.
  optional int32 nanos = 2;
}


enum OptimizationType {
  TYPE_UNSPECIFIED = 0;
  // This optimization blocks JavaScript on the page.
  NOSCRIPT = 1;
  // This optimization applies a set of ResourceLoadingHint(s) to load the
  // page.
  RESOURCE_LOADING = 2;
  // This optimization redirects the navigation through a lite page server.
  LITE_PAGE_REDIRECT = 3;
  // This optimization does nothing (no-op).
  OPTIMIZATION_NONE = 4;
  // This optimization defers execution of parser-blocking script until after
  // parsing completes.
  DEFER_ALL_SCRIPT = 5;
  // This optimization is used to provide aggregated performance information
  // about the page and pages it links to.
  PERFORMANCE_HINTS = 6;
  // This optimization allows page loads going through the data reduction
  // proxy to be transformed by the proxy.
  LITE_PAGE = 7;
  // This optimization compresses public images.
  COMPRESS_PUBLIC_IMAGES = 8;
  // This optimization provides the Loading Predictor with resources predicted
  // to be on the page.
  LOADING_PREDICTOR = 9;
}

// Presents semantics for how page load URLs should be matched.
enum KeyRepresentation {
  REPRESENTATION_UNSPECIFIED = 0;
  // The suffix to match in the hostname of a page load URL.
  //
  // Example: A host suffix of example.com would match pages with host
  // sports.example.com, but not fooexample.com.
  HOST_SUFFIX = 1;
  // The full URL to match.
  //
  // This will be an exact match of a page load URL, including query params and
  // fragments.
  FULL_URL = 2;
}

message Optimization {
  reserved 2, 3;
  // The type of optimization the hint applies to.
  optional OptimizationType optimization_type = 1;
  // The experiment name that activates the optimization.
  //
  // If a non-empty name is provided, the optimization will be disabled unless
  // an experiment of that same name is running. An empty name is not
  // experimental.
  //
  // Optimization Hints experiments are enabled and configured by passing an
  // experiment_name parameter to the OptimizationHintsExperiments feature.
  // For example, if experiment_name is my_exp, it could be enabled with the
  // following command-line flags:
  //   --enable-features=OptimizationHintsExperiments<MyFieldTrial
  //   --force-fieldtrial-params="MyFieldTrial.Enabled:experiment_name/my_exp"
  //   --force-fieldtrials=MyFieldTrial/Enabled/
  optional string experiment_name = 4;
  // The experiment name that should be excluded from using this optimization.
  //
  // If a non-empty name is provided and the client is in an experiment of that
  // same name, the optimization will be disabled and skipped for that client.
  // An empty name is not experimental.
  optional string excluded_experiment_name = 5;
  // The metadata associated with the optimization type.
  //
  // It is expected that the client and server have agreed upon the appropriate
  // metadata type for the optimization type.
  oneof metadata {
    PreviewsMetadata previews_metadata = 10;
    PerformanceHintsMetadata performance_hints_metadata = 11;
    PublicImageMetadata public_image_metadata = 12;
    LoadingPredictorMetadata loading_predictor_metadata = 13;
  }
}

message PageHint {
  // The pattern to match against the committed page URL.
  //
  // The pattern may be a single substring to match against the full URL or it
  // may be an ordered set of substrings to match where the substrings are
  // separated by the ‘*’ wildcard character (with an implicit ‘*’ at the
  // beginning and end).
  optional string page_pattern = 1;
  // The maximum effective connection type threshold for triggering the
  // optimization associated with this hint.
  optional EffectiveConnectionType max_ect_trigger = 2 [deprecated = true];
  // An ordered set of optimizations that should be whitelisted for this page
  // pattern.
  //
  // The client will use the first optimization that it supports.
  repeated Optimization whitelisted_optimizations = 3;
}

message Hint {
  reserved 3;

  // Describes the granularity of the key field.
  optional KeyRepresentation key_representation = 1;
  // The key that applies to this hint. The key_representation field describes
  // the form in which this key takes. Guaranteed to be non-empty.
  optional string key = 2;
  // An ordered set of per-page hints. Only the first PageHint record
  // that matches a committed page URL should be used for that page load.
  repeated PageHint page_hints = 4;
  // Version that generated this hint.
  //
  // It is expected that this version be sent along with subsequent requests
  // for hosts that match this hint.
  optional string version = 5;
  // The maximum duration for which the hint should be used for.
  optional Duration max_cache_duration = 6;
}

// Configuration and data for a Bloom filter.
//
// Note that some additional aspects of the BloomFilter are separately
// specified between the client and server including the specific MurmurHash3
// hashing function, how the hashing function is seeded, how bits are
// addressed in the byte vector, and the nature of the strings that the
// Bloom filter holds (whether host, host suffix, URL path, etc.).
message BloomFilter {
  // Specifies the number of hash functions to use in the Bloom filter.
  // This essentially means how many bits will be set in the bit array
  // for a string member of the Bloom filter.
  optional uint32 num_hash_functions = 1;
  // The number of bits in the Bloom filter's bit array.
  optional uint32 num_bits = 2;
  // The bit array data of the Bloom filter provided via a byte vector.
  // The number of bytes provided must be large enough to hold the
  // specified number of bits (num_bits).
  optional bytes data = 3;
}

// A scalable filter for an optimization type. Initially, this is used to
// provide a large scale blacklist but might be used for whitelists in
// the future.
message OptimizationFilter {
  // The type of optimization this filter applies to.
  optional OptimizationType optimization_type = 1;
  // The filter data represented as a Bloom filter.
  optional BloomFilter bloom_filter = 2;
  // Additional filters represented as regexps matched against the main page
  // URL.
  repeated string regexps = 3;
}

message Configuration {
  // An ordered list containing hints for key/optimization combinations.
  //
  // It is guaranteed that there will only be a single hint per key and key
  // representation combination. These hints are intended to apply to a full
  // page.
  //
  // Note, this list may contain multiple hints that apply to a page. For
  // example, if there are hints for (HOST_SUFFIX,example.com) and
  // (HOST_SUFFIX,sports.example.com), these may both apply to
  // sports.example.com/foo.
  //
  // The client will use the first Hint record with a key that matches the
  // main frame URL. Therefore, the server should provide all the hint
  // details for that key that it wants to provide as the client will only
  // look at that one record to decide which optimization to apply.
  repeated Hint hints = 1;
  // A list of per-optimization blacklists.
  repeated OptimizationFilter optimization_blacklists = 2;
}

message Timestamp {
  // Represents seconds of UTC time since Unix epoch
  // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
  // 9999-12-31T23:59:59Z inclusive.
  optional int64 seconds = 1;

  // Non-negative fractions of a second at nanosecond resolution. Negative
  // second values with fractions must still have non-negative nanos values
  // that count forward in time. Must be from 0 to 999,999,999
  // inclusive.
  optional int32 nanos = 2;
}

enum HintSource {
  HINT_SOURCE_UNKNOWN = 0;
  // Served from the Chrome Optimization Hints Component.
  HINT_SOURCE_OPTIMIZATION_HINTS_COMPONENT = 1;
  // Served from the Chrome Optimization Guide Service.
  HINT_SOURCE_OPTIMIZATION_GUIDE_SERVICE = 2;
}

message Version {
  reserved 2;

  // The time the hint was generated.
  optional Timestamp generation_timestamp = 1;
  // The source from which the hint was served from.
  optional HintSource hint_source = 3;
}
