import click

from hatch.config.constants import PublishEnvVars


@click.command(short_help='Publish build artifacts')
@click.argument('artifacts', nargs=-1)
@click.option(
    '--repo',
    '-r',
    envvar=PublishEnvVars.REPO,
    help='The repository with which to publish artifacts [env var: `HATCH_INDEX_REPO`]',
)
@click.option(
    '--user', '-u', envvar=PublishEnvVars.USER, help='The user with which to authenticate [env var: `HATCH_INDEX_USER`]'
)
@click.option(
    '--auth',
    '-a',
    envvar=PublishEnvVars.AUTH,
    help='The credentials to use for authentication [env var: `HATCH_INDEX_AUTH`]',
)
@click.option(
    '--ca-cert',
    envvar=PublishEnvVars.CA_CERT,
    help='The path to a CA bundle [env var: `HATCH_INDEX_CA_CERT`]',
)
@click.option(
    '--client-cert',
    envvar=PublishEnvVars.CLIENT_CERT,
    help='The path to a client certificate, optionally containing the private key [env var: `HATCH_INDEX_CLIENT_CERT`]',
)
@click.option(
    '--client-key',
    envvar=PublishEnvVars.CLIENT_KEY,
    help="The path to the client certificate's private key [env var: `HATCH_INDEX_CLIENT_KEY`]",
)
@click.option('--no-prompt', '-n', is_flag=True, help='Disable prompts, such as for missing required fields')
@click.option(
    '--initialize-auth', is_flag=True, help='Save first-time authentication information even if nothing was published'
)
@click.option(
    '--publisher',
    '-p',
    'publisher_name',
    envvar=PublishEnvVars.PUBLISHER,
    default='index',
    help='The publisher plugin to use (default is `index`) [env var: `HATCH_PUBLISHER`]',
)
@click.option(
    '--option',
    '-o',
    'options',
    envvar=PublishEnvVars.OPTIONS,
    multiple=True,
    help=(
        'Options to pass to the publisher plugin. This may be selected multiple '
        'times e.g. `-o foo=bar -o baz=23` [env var: `HATCH_PUBLISHER_OPTIONS`]'
    ),
)
@click.option('--yes', '-y', is_flag=True, help='Confirm without prompting when the plugin is disabled')
@click.pass_obj
def publish(
    app,
    artifacts,
    repo,
    user,
    auth,
    ca_cert,
    client_cert,
    client_key,
    no_prompt,
    initialize_auth,
    publisher_name,
    options,
    yes,
):
    """Publish build artifacts."""
    option_map = {'no_prompt': no_prompt, 'initialize_auth': initialize_auth}
    if publisher_name == 'index':
        if options:
            app.abort('Use the standard CLI flags rather than passing explicit options when using the `index` plugin')

        if repo:
            option_map['repo'] = repo
        if user:
            option_map['user'] = user
        if auth:
            option_map['auth'] = auth
        if ca_cert:
            option_map['ca_cert'] = ca_cert
        if client_cert:
            option_map['client_cert'] = client_cert
        if client_key:
            option_map['client_key'] = client_key
    else:  # no cov
        for option in options:
            key, _, value = option.partition('=')
            option_map[key] = value

    publisher_class = app.plugins.publisher.get(publisher_name)
    if publisher_class is None:
        app.abort(f'Unknown publisher: {publisher_name}')

    publisher = publisher_class(
        app.get_safe_application(),
        app.project.location,
        app.cache_dir / 'publish' / publisher_name,
        app.project.config.publish.get(publisher_name, {}),
        app.config.publish.get(publisher_name, {}),
    )
    if publisher.disable and not (yes or (not no_prompt and app.confirm(f'Confirm `{publisher_name}` publishing'))):
        app.abort(f'Publisher is disabled: {publisher_name}')

    publisher.publish(list(artifacts), option_map)
