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

[Discoverable]
interface ModuleResolver {
    // Finds Modules (contained in Fuchsia packages) that satisfy the constraints
    // specified in |query|. Module resolution is done by matching the requested
    // |query.action| and |query.parameter_constraints| (with both names and
    // types) against actions and constraints specified in module manifests.
    //
    // If no results could be found, |response.results| will be empty.
    //
    // For detailed information on the resolution process, see
    // docs/modular/module_resolution.md.
    //
    // TODO(thatguy): Offer some kind of fallback instruction/option to clients
    // in the case of no results.
    1: FindModules(FindModulesQuery query) -> (FindModulesResponse response);

    // Find modules that satisfy the constraints specified in |query|. Module
    // resolution for this method is done by matching only the requested types
    // specified in |query.parameter_constriants|. This type of query is useful
    // for finding possible actions that satisfy a set of parameter types.
    //
    // Each module result in the response will provide a mapping from the
    // constraint names in |query| to the parameter names of a module result. If
    // no results could be found, |response.results| will be empty.
    2: FindModulesByTypes(FindModulesByTypesQuery query)
           -> (FindModulesByTypesResponse response);

    // If |module_id| could not be found or does not have a manifest, returns a
    // null |contents|.
    3: GetModuleManifest(string module_id) -> (ModuleManifest? contents);
};

// Mirrors the information present in a Intent. Where a Intent is meant to
// interface between Modules and the Framework, this structure is specific to
// the interface between the Framework and the ModuleResolver.
//
// In that role, it has references to structures and concepts that are only
// visible within the abstraction layer of the Framework.
// TODO(thatguy): Add scoring info here.
struct FindModulesQuery {
    // The handler is a module URL; if the handler is specified, the search for
    // (action, parameter_constraints) is scoped within the specified handler.
    string? handler;
    string action;
    vector<FindModulesParameterConstraint> parameter_constraints;
};

struct FindModulesParameterConstraint {
    string param_name;
    vector<string> param_types;
};

enum FindModulesStatus {
    // A search was successfully conducted.
    SUCCESS = 0;
    // |FindModulesQuery.handler| was specified but the resolver doesn't know
    // about it.
    UNKNOWN_HANDLER = 1;
};

struct FindModulesResponse {
    FindModulesStatus status;
    vector<FindModulesResult> results;
};

struct FindModulesResult {
    // The ID of the Module. For now, this is the URL of the Module binary.
    string module_id;

    // The Module's manifest file (see docs/manifests/module.md).
    ModuleManifest? manifest;
    // TODO(thatguy): Add debug info.
};

struct FindModulesByTypesQuery {
    // Even though only |param_types| are used to search for possible modules,
    // each module result comes with a mapping from constraint_name =>
    // param_name.
    vector<FindModulesByTypesParameterConstraint> parameter_constraints;
};

struct FindModulesByTypesParameterConstraint {
    // This |constraint_name| is associated with a module result's |param_name|;
    string constraint_name;
    vector<string> param_types;
};

struct FindModulesByTypesResponse {
    // One result per (module_id, action, param mapping) tuple.
    // TODO(vardhan): For efficiency, consider grouping the results differently so
    // there aren't repeated transmissions of a manifest.
    vector<FindModulesByTypesResult> results;
};

struct FindModulesByTypesResult {
    float64 score;

    // The ID of the Module. For now, this is the URL of the Module package.
    string module_id;
    string action;

    // The Module's manifest file (see docs/manifests/module.md)
    ModuleManifest? manifest;

    // A list of mappings from query_constraint_name => result_param_name
    vector<FindModulesByTypesParameterMapping> parameter_mappings;
};

// Defines a single mapping entry from a specified constraint name to a module
// result's parameter name.
struct FindModulesByTypesParameterMapping {
    // This is the constraint name as specified in
    // |FindModulesByTypesParameterConstraint.constraint_name|.
    string query_constraint_name;
    // This is the associated parameter name from a module result.
    string result_param_name;
};
