# Copyright 2020 The Bazel Authors. All rights reserved.
#
# 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.
"""Generates a fish completion script for Bazel."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import re
import subprocess
import tempfile

from absl import app
from absl import flags

flags.DEFINE_string('bazel', None, 'Path to the bazel binary')
flags.DEFINE_string('output', None, 'Where to put the generated fish script')

flags.mark_flag_as_required('bazel')
flags.mark_flag_as_required('output')

FLAGS = flags.FLAGS
_BAZEL = 'bazel'
_FISH_SEEN_SUBCOMMAND_FROM = '__fish_seen_subcommand_from'
_FISH_BAZEL_HEADER = """#!/usr/bin/env fish
# Copyright 2020 The Bazel Authors. All rights reserved.
#
# 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.

# Fish completion for Bazel commands and options.
#
# This script was generated from a specific Bazel build distribution. See
# https://github.com/bazelbuild/bazel/blob/master/scripts/generate_fish_completion.py
# for details and implementation.
"""
_FISH_BAZEL_COMMAND_LIST_VAR = 'BAZEL_COMMAND_LIST'
_FISH_BAZEL_SEEN_SUBCOMMAND = '__bazel_seen_subcommand'
_FISH_BAZEL_SEEN_SUBCOMMAND_DEF = """
function {} -d "Checks whether the current command line contains a bazel subcommand."
    {} ${}
end
""".format(_FISH_BAZEL_SEEN_SUBCOMMAND, _FISH_SEEN_SUBCOMMAND_FROM,
           _FISH_BAZEL_COMMAND_LIST_VAR)


class BazelCompletionWriter(object):
  """Constructs a Fish completion script for Bazel."""

  def __init__(self, bazel, output_user_root):
    """Initializes writer state.

    Args:
        bazel: String containing a path to the bazel binary to run.
        output_user_root: String path to user root directory used for
          running bazel commands.
    """
    self._bazel = bazel
    self._output_user_root = output_user_root
    self._startup_options = self._get_options_from_bazel(
        ('help', 'startup_options'))
    self._bazel_help_completion_text = self._get_bazel_output(
        ('help', 'completion'))
    self._param_types_by_subcommand = self._get_param_types()
    self._subcommands = self._get_subcommands()

  def write_completion(self, output_file):
    """Writes a Fish completion script for Bazel to an output file.

    Args:
        output_file: File object opened in a writable mode.
    """
    output_file.write(_FISH_BAZEL_HEADER)
    output_file.write('set {} {}\n'.format(
        _FISH_BAZEL_COMMAND_LIST_VAR,
        ' '.join(c.name for c in self._subcommands)))
    output_file.write(_FISH_BAZEL_SEEN_SUBCOMMAND_DEF)
    for opt in self._startup_options:
      opt.write_completion(output_file)
    for sub in self._subcommands:
      sub.write_completion(output_file)

  def _get_bazel_output(self, args):
    return subprocess.check_output(
        (self._bazel, '--output_user_root={}'.format(self._output_user_root)) +
        tuple(args),
        universal_newlines=True)

  def _get_options_from_bazel(self, bazel_args, **kwargs):
    output = self._get_bazel_output(bazel_args)
    return list(
        Arg.generate_from_help(
            r'^\s*--(\[no\])?(?P<name>\w+)\s+\((?P<desc>.*)\)$', output,
            **kwargs))

  def _get_param_types(self):
    param_types = {}
    for match in re.finditer(
        r'^BAZEL_COMMAND_(?P<subcommand>.*)_ARGUMENT="(?P<type>.*)"$',
        self._bazel_help_completion_text, re.MULTILINE):
      sub = self._normalize_subcommand_name(match.group('subcommand'))
      param_types[sub] = match.group('type')
    return param_types

  def _get_subcommands(self):
    """Runs `bazel help` and parses its output to derive Bazel commands.

    Returns:
        (:obj:`list` of :obj:`Arg`): List of Bazel commands.
    """
    subs = []
    output = self._get_bazel_output(('help',))
    block = re.search(r'Available commands:(.*\n\n)', output, re.DOTALL)
    for sub in Arg.generate_from_help(
        r'^\s*(?P<name>\S+)\s*(?P<desc>\S+.*\.)\s*$',
        block.group(1),
        is_subcommand=True):
      sub.sub_opts = self._get_options_from_bazel(('help', sub.name),
                                                  expected_subcommand=sub.name)
      sub.sub_params = self._get_params(sub.name)
      subs.append(sub)
    return subs

  _BAZEL_QUERY_BY_LABEL = {
      'label': r'//...',
      'label-bin': r'kind(".*_binary", //...)',
      'label-test': r'tests(//...)',
  }

  def _get_params(self, subcommand):
    """Produces a list of param completions for a given Bazel command.

    Uses a previously generated mapping of Bazel commands to parameter types
    to determine how to complete params following a given command. For
    example, `bazel build` expects `label` type params, whereas `bazel info`
    expects an `info-key` type. The param type is finally translated into a
    list of completion strings.

    Args:
        subcommand: Bazel command string.

    Returns:
        (:obj:`list` of :obj:`str`): List of completions based on the param
            type for the given Bazel command.
    """
    name = self._normalize_subcommand_name(subcommand)
    if name not in self._param_types_by_subcommand:
      return []
    params = []
    param_type = self._param_types_by_subcommand[name]
    if param_type.startswith('label'):
      query = self._BAZEL_QUERY_BY_LABEL[param_type]
      params.append("({} query -k '{}' 2>/dev/null)".format(_BAZEL, query))
    elif param_type.startswith('command'):
      match = re.match(r'command\|\{(?P<commands>.*)\}', param_type)
      params.extend(match.group('commands').split(','))
    elif param_type == 'info-key':
      match = re.search(r'BAZEL_INFO_KEYS="(?P<keys>[^"]*)"',
                        self._bazel_help_completion_text)
      params.extend(match.group('keys').split())
    return params

  @staticmethod
  def _normalize_subcommand_name(subcommand):
    return subcommand.strip().lower().replace('_', '-')


class Arg(object):
  """Represents a Bazel argument and its metadata.

    Attributes:
        name: String containing the name of the argument.
        desc: String describing the argument usage.
        is_subcommand: True if this arg represents a Bazel subcommand. Defaults
          to False, indicating that this arg is an option flag.
        expected_subcommand: Nullable string containing a subcommand that this
          option must follow. Defaults to None, indicating that this option or
          subcommand must not follow another subcommand.
        sub_opts: List of Args representing options of a subcommand. Used only
          if is_subcommand is True.
        sub_params: List of Args representing parameters of a subcommand. Used
          only if is_subcommand is True.
  """

  def __init__(self,
               name,
               desc=None,
               is_subcommand=False,
               expected_subcommand=None):
    self.name = name
    self.desc = desc
    self.is_subcommand = is_subcommand
    self.expected_subcommand = expected_subcommand
    self.sub_opts = []
    self.sub_params = []
    self._is_boolean = (self.desc and self.desc.startswith('a boolean'))

  @classmethod
  def generate_from_help(cls, line_regex, text, **kwargs):
    """Generates Arg objects using a line regex on a block of help text.

    Args:
        line_regex: Regular expression string to match a line of text.
        text: String of help text to parse.
        **kwargs: Extra keywords to pass into the Arg constructor.

    Yields:
        Arg objects parsed from the help text.
    """
    for match in re.finditer(line_regex, text, re.MULTILINE):
      kwargs.update(match.groupdict())
      yield cls(**kwargs)

  def write_completion(self, output_file, command=_BAZEL):
    """Writes Fish completion commands to a file.

        Uses the metadata stored in this class to write Fish shell commands
        that enable completion for this Bazel argument.

    Args:
        output_file: File object to write completions into. Must be open in
          a writable mode.
        command: String containg the command name (i.e. "bazel").
    """
    args = self._get_complete_args_base(
        command=command, subcommand=self.expected_subcommand)

    # Argument can be subcommand or option flag.
    if self.is_subcommand:
      args.append('-xa')  # Exclusive subcommand argument.
    else:
      args.append('-l')  # Long option.
    args.append('"{}"'.format(self.name))
    name_index = len(args) - 1

    if self.desc:
      args.extend(('-d', '"{}"'.format(self._escape(self.desc))))

    if not self._is_boolean:
      args.append('-r')  # Require a subsequent parameter.

    # Write completion commands to the file.
    output_file.write(self._complete(args))
    if self._is_boolean:
      # Include the "false" version of a boolean option.
      args[name_index] = '"no{}"'.format(self.name)
      output_file.write(self._complete(args))
    if self.is_subcommand:
      for opt in self.sub_opts:
        opt.write_completion(output_file, command=command)
      self._write_params_completion(output_file, command=command)
      output_file.write('\n')

  def _write_params_completion(self, output_file, command=_BAZEL):
    args = self._get_complete_args_base(command, subcommand=self.name)
    if self.sub_params:
      args.extend(
          ('-fa', '"{}"'.format(self._escape(' '.join(self.sub_params)))))
    output_file.write(self._complete(args))

  @staticmethod
  def _get_complete_args_base(command, subcommand=None):
    """Provides basic arguments for all fish `complete` invocations.

    Args:
        command: Name of the Bazel executable (i.e. "bazel").
        subcommand: Optional Bazel command like "build".

    Returns:
        (:obj:`list` of :obj:`str`): List of args for `complete`.
    """
    args = ['-c', command]

    # Completion pre-condition.
    args.append('-n')
    if subcommand:
      args.append('"{} {}"'.format(_FISH_SEEN_SUBCOMMAND_FROM, subcommand))
    else:
      args.append('"not {}"'.format(_FISH_BAZEL_SEEN_SUBCOMMAND))

    return args

  @staticmethod
  def _complete(args):
    return 'complete {}\n'.format(' '.join(args))

  @staticmethod
  def _escape(text):
    return text.replace('"', r'\"')


def main(argv):
  """Generates fish completion using provided flags."""
  del argv  # Unused.
  with tempfile.TemporaryDirectory() as output_user_root:
    writer = BazelCompletionWriter(FLAGS.bazel, output_user_root)
    with open(FLAGS.output, mode='w') as output:
      writer.write_completion(output)


if __name__ == '__main__':
  app.run(main)
