// 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 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;
};

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

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

    GetProcessState(handle<channel> ch);

    // 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);
};

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