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

library fuchsia.amber;

using fuchsia.pkg;
using zx;

struct OAuth2Config {
    string clientId;

    string clientSecret = "";

    string authUrl;
    string tokenUrl;
    vector<string> scopes;
    string deviceCodeUrl;
};

struct DeviceCode {
    string userCode;
    string verificationUrl;
    int64 expiresIn;
};

struct KeyConfig {
    // Supported TUF key types. The only supported algorithm is ed25519.
    string type;

    // The value of the key encoded in hex.
    string value;
};

struct TLSClientConfig {
    // If insecureSkipTlsVerify is true, TLS will accept any certificate
    // provided by the server. This should only be used for testing.
    bool insecureSkipVerify = false;

    // The set of root certificate authorities that clients use when verifying
    // server certificates. If the list is empty, TLS uses the host's root CA
    // set.
    vector<string> rootCAs;
};

struct TransportConfig {
    // If true, prevent re-use of TCP connections between HTTP requests.
    bool disableKeepAlives = false;

    // The keep-alive period for an active network connection. A zero value
    // means that we use the system default.
    int32 KeepAlive = 0;

    // The maximum number of idle (keep-alive) connections across all hosts. A
    // zero value means that we use the system default.
    int32 maxIdleConns = 0;

    // The maximum number of idle (keep-alive) connections across for each
    // host. A zero value means we use the system default.
    int32 maxIdleConnsPerHost = 0;

    // The maximum amount of time to wait for a connection to complete in
    // milliseconds. A zero value means we use the system default.
    int32 connectTimeout = 0;

    // The deadline in milliseconds for a request to complete. A zero value
    // means that we use the system default.
    int32 requestTimeout = 0;

    // The maximum amount of time in milliseconds an idle (keep-alive)
    // connection will remain idle before closing itself. A zero value means
    // that we use the system default.
    int32 idleConnTimeout = 0;

    // The amount of time to wait for a server's response headers. A zero value
    // means that we use the system default.
    int32 responseHeaderTimeout = 0;

    // The deadline in milliseconds to wait for a server's first response
    // headers if the request has an "Expect: 100-continue" header. A zero
    // value means that we use the system default.
    int32 expectContinueTimeout = 0;

    // The deadline in milliseconds to wait for a TLS handshake. Zero means that we use the system
    // default.
    int32 tlsHandshakeTimeout = 0;

    TLSClientConfig? tlsClientConfig;
};

struct StatusConfig {
    bool enabled;
};

struct SourceConfig {
    // A unique identifier that distinquishes this source from others.
    string id;

    // The canonical URL for the TUF repository.
    string repoUrl;

    // Optionally download package blobs from this repository. If not
    // specified, blobs will be fetched from `$repoUrl/blobs`.
    string blobRepoUrl = "";

    // The rate limit indicates the number of requests per rateReriod,
    // expressed in milliseconds. A limit or period of zero means there is no
    // limit.
    uint64 rateLimit;

    // The TUF metadata will be refreshed after it is ratePeriod seconds stale.
    int32 ratePeriod = 3600;

    // A vector of public keys. These keys must match one of the trusted keys
    // known to the system.
    vector<KeyConfig> rootKeys;

    TransportConfig? transportConfig;

    OAuth2Config? oauth2Config;

    StatusConfig? statusConfig;

    // If true, the source supports the /auto SSE endpoint for live updates
    bool auto = false;

    BlobEncryptionKey? blobKey;
};

struct BlobEncryptionKey {
    array<uint8>:32 data;
};

enum Status {
    OK = 0;
    ERR = 1;
    ERR_NOT_FOUND = 2;
};

[Discoverable]
protocol Control {
    // simple no-op that can be used to test the connection
    DoTest(int32 input) -> (string output);

    // Add a TUF source repository.
    AddSrc(SourceConfig source) -> (bool res);

    // Remove a TUF source repository. SourceConfigs that were bundled when the
    // system was built may be removed, but that funcionality may change in the
    // future. See PKG-150.
    RemoveSrc(string id) -> (Status res);

    // Get the list of URLs of the current set of sources
    ListSrcs() -> (vector<SourceConfig> srcs);

    // Get a content blob identified by the given hashed Merkle root.
    // This operation is asynchronous and provides no results.
    GetBlob(string merkle);

    PackagesActivated(vector<string> merkle);

    // Get an update for the package identified by 'name' which has the
    // provided version. If no version is supplied, the latest available
    // version of that package will be retrieved. The package data is sent to
    // PackageFS which then stores the package in BlobFS. This method returns
    // a channel that will provide the ultimate results. The channel will become
    // readable when the update is complete. If at that time the User0 signal is
    // set on the channel, the result is an error string that may be read from
    // the channel, otherwise the result is success, and the new merkleroot can
    // be read from the channel.
    GetUpdateComplete(string name, string? version, string? merkle)
        -> (handle<channel> rplyChan);

    CheckForSystemUpdate() -> (bool res);

    // Log into the source specified by the source id. Returns the oauth2
    // device flow code if the source is configured for authentication, or null
    // if not.
    Login(string sourceId) -> (DeviceCode? device);

    SetSrcEnabled(string id, bool enabled) -> (Status res);

    // Trigger a garbage collection.
    GC();

    // Sent when a blob fails to write, causing one or more package installs to
    // permanently fail.
    PackagesFailed(vector<string> merkle, zx.status error, string blob_merkle);

    // Opens a TUF repository specified by the provided RepositoryConfig.
    // The repository will stay open for the life of the OpenedRepository
    // channel.
    //
    // Packages in the opened repository can be accessed via
    // OpenedRepository.GetUpdateComplete, but will not appear in calls to
    // the global GetUpdateComplete, above.
    OpenRepository(fuchsia.pkg.RepositoryConfig config, request<OpenedRepository> repo) -> (zx.status result);
};

[Discoverable]
protocol Events {
    // Event that is triggered when an update failed because blobfs is out of
    // storage.
    -> OnOutOfSpace();
};

protocol OpenedRepository {
    // Get an update for the package identified by 'name' which has the
    // provided variant. The package data is sent to PackageFS which then
    // stores the package in BlobFS. This method provides a FetchResult that
    // will send the ultimate results.
    GetUpdateComplete(string name, string? variant, string? merkle, request<FetchResult> result);
};

// A protocol providing results for a OpenedRepository.GetUpdateComplete call.
// Only one event will be sent before the channel is closed.
protocol FetchResult {
    // Sent when the package is successfully installed and available for use.
    -> OnSuccess(string merkle);
    // Sent when the package fails to install for some reason.
    -> OnError(zx.status result, string message);
};
