# 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 the a 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)
