#!/usr/bin/env python3
# Copyright (C) 2022 The Android Open Source Project
#
# 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 re
from typing import Union, List, Tuple

from python.generators.stdlib_docs import stdlib
from python.generators.stdlib_docs.utils import Errors, Pattern, get_text, fetch_comment, match_pattern


def parse_desc(docs: 'stdlib.AnyDocs') -> str:
  desc_lines = [get_text(line, False) for line in docs.desc]
  return ' '.join(desc_lines).strip('\n').strip()


# Whether comment segment about columns contain proper schema. Can be matched
# against parsed SQL data by setting `use_data_from_sql`.
def parse_columns(docs: Union['stdlib.TableViewDocs', 'stdlib.ViewFunctionDocs']
                 ) -> dict:
  cols = {}
  last_col = None
  last_desc = []
  for line in docs.columns:
    # Ignore only '--' line.
    if line == "--" or not line.startswith("-- @column"):
      last_desc.append(get_text(line))
      continue

    # Look for '-- @column' line as a column description
    m = re.match(Pattern['column'], line)
    if last_col:
      cols[last_col] = ' '.join(last_desc)
    if not m:
      print(f'Expected line {line} to match @column format', file=sys.stderr)
    last_col, last_desc = m.group(1), [m.group(2)]

  cols[last_col] = ' '.join(last_desc)
  return cols


def parse_args(docs: "stdlib.FunctionDocs") -> dict:
  if not docs.args:
    return {}

  args = {}
  last_arg, last_desc, last_type = None, [], None
  for line in docs.args:
    # Ignore only '--' line.
    if line == "--" or not line.startswith("-- @arg"):
      last_desc.append(get_text(line))
      continue

    m = re.match(Pattern['args'], line)
    if last_arg:
      args[last_arg] = {'type': last_type, 'desc': ' '.join(last_desc)}
    last_arg, last_type, last_desc = m.group(1), m.group(2), [m.group(3)]

  args[last_arg] = {'type': last_type, 'desc': ' '.join(last_desc)}
  return args


# Whether comment segment about return contain proper schema. Matches against
# parsed SQL data.
def parse_ret(docs: "stdlib.FunctionDocs") -> Tuple[str, str]:
  desc = []
  for line in docs.ret:
    # Ignore only '--' line.
    if line == "--" or not line.startswith("-- @ret"):
      desc.append(get_text(line))

    m = re.match(Pattern['return_arg'], line)
    if not m:
      print(f'Expected line {line} to match @ret format', file=sys.stderr)
    ret_type, desc = m.group(1), [m.group(2)]
  return (ret_type, ' '.join(desc))


# After matching file to Pattern, fetches and validates related documentation.
def parse_typed_docs(path: str, module: str, sql: str, Pattern: str,
                     docs_object: type
                    ) -> Tuple[List['stdlib.AnyDocs'], Errors]:
  errors = []
  line_id_to_match = match_pattern(Pattern, sql)
  lines = sql.split("\n")
  all_typed_docs = []
  for line_id, matches in line_id_to_match.items():
    # Fetch comment by looking at lines over beginning of match in reverse
    # order.
    comment = fetch_comment(lines[line_id - 1::-1])
    typed_docs, obj_errors = docs_object.create_from_comment(
        path, comment, module, matches)
    errors += obj_errors

    if not typed_docs:
      continue

    errors += typed_docs.check_comment()

    if not errors:
      all_typed_docs.append(typed_docs)

  return all_typed_docs, errors
