# Copyright 2017-2023 Posit Software, PBC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import click

from guild import click_util

from . import runs_support
from . import remote_support

# List of formatted run attrs supported by select with attr.
_RUN_UTIL_FORMAT_ATTRS = [
    "command",
    "duration",
    "exit_status",
    "from",
    "id",
    "index",
    "label",
    "marked",
    "model",
    "op_name",
    "operation",
    "pid",
    "pkg_name",
    "run_dir",
    "short_id",
    "sourcecode_digest",
    "started",
    "status",
    "stopped",
    "vcs_commit",
]


def _ac_attr(ctx, _param, incomplete):
    attrs = set(_RUN_UTIL_FORMAT_ATTRS)
    runs = runs_support.runs_for_ctx(ctx)
    if runs:
        attrs.update(runs[0].attr_names())
    return sorted([name for name in attrs if name.startswith(incomplete)])


@click.command()
@runs_support.runs_arg
@click.option(
    "-A",
    "--all",
    help="Select all matching runs, not just the latest.",
    is_flag=True,
)
@click.option(
    "-min",
    "--min",
    metavar="COLSPEC",
    help="Select the run with the lowest value for the specified COLSPEC.",
)
@click.option(
    "-max",
    "--max",
    metavar="COLSPEC",
    help="Select the run with the highest value for the specified COLSPEC.",
)
@click.option("-s", "--short-id", help="Use short ID.", is_flag=True)
@click.option(
    "-a",
    "--attr",
    metavar="ATTR",
    help="Show specified run attribute rather than run ID.",
    shell_complete=_ac_attr,
)
@click.option("-p", "--path", "--dir", help="Show run path.", is_flag=True)
@runs_support.all_filters
@remote_support.remote_option("Run the operation remotely.")
@click.pass_context
@click_util.use_args
@click_util.render_doc
def select(ctx, args):
    """Select a run and shows its ID.

    This command is generally used when specifying a run ID for
    another Guild command. For example, to restart the latest `train`
    run:

        `guild run --restart $(guild select -o train)`

    {{ runs_support.run_arg }}

    If RUN isn't specified, the latest matching run is selected.

    ### Selecting Min or Max Scalar

    To select the run with the lowest or highest column value, use
    `--min` or `--max` respectively. For example, to select the run
    with the lowest `loss` scalar value, use `--min loss`.

    For help with COLSPEC formatting, see `COLUMN SPECS` in `compare`
    help by running `guild compare --help`.

    Other run filters are applied before selecting a minimum or
    maximium scalar value.

    {{ runs_support.all_filters }}

    ### Select remote rnus

    To apply `select` to remote runs, specify `--remote REMOTE`. Use
    ``guild remotes`` to list available remotes.

    For information on configuring remotes, see ``guild remotes
    --help``.

    """
    from . import runs_impl

    runs_impl.select(args, ctx)
