# 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.
"""API for Bazel calls for config, cquery, and required fragment info.

There's no Python Bazel API so we invoke Bazel as a subprocess.
"""

import json
import os
import subprocess
from typing import Callable
from typing import List
from typing import Tuple
from frozendict import frozendict
from scripts.ctexplain.ctexplain_types import Configuration
from scripts.ctexplain.ctexplain_types import ConfiguredTarget
from scripts.ctexplain.ctexplain_types import HostConfiguration
from scripts.ctexplain.ctexplain_types import NullConfiguration


def run_bazel_in_client(args: List[str]) -> Tuple[int, List[str], List[str]]:
  """Calls bazel within the current workspace.

  For production use. Tests use an alternative invoker that goes through test
  infrastructure.

  Args:
    args: the arguments to call Bazel with

  Returns:
    Tuple of (return code, stdout, stderr)
  """
  result = subprocess.run(
      ["blaze"] + args,
      cwd=os.getcwd(),
      stdout=subprocess.PIPE,
      stderr=subprocess.PIPE,
      check=False,
  )
  return (
      result.returncode,
      result.stdout.decode("utf-8").split(os.linesep),
      result.stderr,
  )


class BazelApi:
  """API that accepts injectable Bazel invocation logic."""

  def __init__(
      self,
      run_bazel: Callable[
          [List[str]], Tuple[int, List[str], List[str]]
      ] = run_bazel_in_client,
  ):
    self.run_bazel = run_bazel

  def cquery(
      self, args: List[str]
  ) -> Tuple[bool, str, Tuple[ConfiguredTarget, ...]]:
    """Calls cquery with the given arguments.

    Args:
      args: A list of cquery command-line arguments, one argument per entry.

    Returns:
      (success, stderr, cts), where success is True iff the query succeeded,
      stderr contains the query's stderr (regardless of success value), and cts
      is the configured targets found by the query if successful, empty
      otherwise.

      ct order preserves cquery's output order. This is topologically sorted
      with duplicates removed. So no unique configured target appears twice and
      if A depends on B, A appears before B.
    """
    base_args = ["cquery", "--show_config_fragments=transitive"]
    returncode, stdout, stderr = self.run_bazel(base_args + args)
    if returncode != 0:
      return (False, stderr, ())

    cts = []
    for line in stdout:
      if not line.strip():
        continue
      ctinfo = _parse_cquery_result_line(line)
      if ctinfo is not None:
        cts.append(ctinfo)

    return (True, stderr, tuple(cts))

  def get_config(self, config_hash: str) -> Configuration:
    """Calls "bazel config" with the given config hash.

    Args:
      config_hash: A config hash as reported by "bazel cquery".

    Returns:
      The matching configuration or None if no match is found.

    Raises:
      ValueError: On any parsing problems.
    """
    if config_hash == "HOST":
      return HostConfiguration()
    elif config_hash == "null":
      return NullConfiguration()

    base_args = ["config", "--output=json"]
    returncode, stdout, stderr = self.run_bazel(base_args + [config_hash])
    if returncode != 0:
      raise ValueError("Could not get config: " + stderr)
    config_json = json.loads(os.linesep.join(stdout))
    fragments = frozendict({
        _base_name(entry["name"]): tuple(
            _base_name(clazz) for clazz in entry["fragmentOptions"]
        )
        for entry in config_json["fragments"]
    })
    options = frozendict({
        _base_name(entry["name"]): frozendict(entry["options"])
        for entry in config_json["fragmentOptions"]
    })
    return Configuration(fragments, options)


# TODO(gregce): have cquery --output=jsonproto support --show_config_fragments
# so we can replace all this regex parsing with JSON reads.
def _parse_cquery_result_line(line: str) -> ConfiguredTarget:
  """Converts a cquery output line to a ConfiguredTarget.

  Expected input is:

      "<label> (<config hash>) [configFragment1, configFragment2, ...]"

  or:
      "<label> (null)"

  Args:
    line: The expected input.

  Returns:
    Corresponding ConfiguredTarget if the line matches else None.
  """
  tokens = line.split(maxsplit=2)
  label = tokens[0]
  if tokens[1][0] != "(" or tokens[1][-1] != ")":
    raise ValueError(f"{tokens[1]} in {line} not surrounded by parentheses")
  config_hash = tokens[1][1:-1]
  if config_hash == "null":
    fragments = ()
  else:
    if tokens[2][0] != "[" or tokens[2][-1] != "]":
      raise ValueError(f"{tokens[2]} in {line} not surrounded by [] brackets")
    # The fragments list looks like '[Fragment1, Fragment2, ...]'. Split the
    # whole line on ' [' to get just this list, then remove the final ']', then
    # split again on ', ' to convert it to a structured tuple.
    fragments = tuple(line.split(" [")[1][0:-1].split(", "))
  return ConfiguredTarget(
      label=label,
      config=None,  # Not yet available: we'll need `bazel config` to get this.
      config_hash=config_hash,
      transitive_fragments=fragments,
  )


def _base_name(full_name: str) -> str:
  """Strips a fully qualified Java class name to the file scope.

  Examples:
    - "A.B.OuterClass" -> "OuterClass"
    - "A.B.OuterClass$InnerClass" -> "OuterClass$InnerClass"

  Args:
    full_name: Fully qualified class name.

  Returns:
    Stripped name.
  """
  return full_name.split(".")[-1]
