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

using fuchsia.mem;

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.
interface 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.
    1: OnProposalAccepted(string proposal_id, string? story_id);
};
