// Copyright 2016 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.modular;

struct Proposal {
    // Identifies a proposal, namespaced internally to the proposing component and
    // proposal channel (Query or Next/Interruption).
    string id;

    // A client-assigned name for the story to which the actions in |on_selected|
    // apply. If a story with the given name already exists (ie, because a past
    // Proposal with the same |story_name| was executed), the actions in
    // |on_selected| will apply to the existing story. Otherwise, a new story is
    // created.
    // If |story_name| is null, a new story is always created.
    // This name is namespaced to the agent that submitted the proposal.
    string? story_name;

    // Used to restrict the proposal potential appearance as a suggestion only
    // when certain story or mod is focused.
    vector<ProposalAffinity> affinity;

    // The list of actions to take when the user selects the associated
    // Suggestion.
    vector<StoryCommand> on_selected;

    // An optional hint about the probability that this proposal would be chosen
    // if it were the only proposal presented to the user. A confidence of 0.0
    // indicates no hint. The confidence assigned by the system may be subject to
    // other considerations such as performance metrics.
    float32 confidence = 0.0;

    // True iff the proposal would like to make use of a rich suggestion. Only
    // certain components are allowed to use rich suggestions.
    bool wants_rich_suggestion = false;

    SuggestionDisplay display;

    // A listener interface that is notified when the proposal is accepted by
    // the system.
    //
    // The listener is currently notified once when a proposal is accepted. Thus
    // the |story_id| provided will be of the first create story action in
    // |on_selected|, and subsequent create story actions will not notify the
    // listener.
    ProposalListener? listener;
};

// Restricts the proposal potential apparance as a suggestion only when
// a story or a mod within a story are focused.
union ProposalAffinity {
    StoryAffinity story_affinity;
    ModuleAffinity module_affinity;
};

// Restricts the proposal to appear only when the story identified by
// |story_name| is focused.
// The name is namespace to the agent that submitted the proposal.
struct StoryAffinity {
    string story_name;
};

// Restricts the proposal to appear only when the module identified by
// |module_name| within the story identified by |story_name| is focused.
// The name is namespace to the agent that submitted the proposal.
struct ModuleAffinity {
    string story_name;
    vector<string> module_name;
};

// An interface that allows Proposal creators to be notified when a proposal
// is accepted by the system.
protocol ProposalListener {
    // Indicates that a proposal was accepted by the system.
    //
    // |proposal_id| The identifier of the accepted proposal.
    // |story_id| The identifier of the created story, if a story was created.
    OnProposalAccepted(string proposal_id, string? story_id);
};
