#!/usr/bin/python3

import sys
import os
import glob
import re
import jinja2

def main():
  if len(sys.argv) < 3:
    print(f"Usage: {os.path.basename(__file__)} bug-list.txt template.txt")
    sys.exit(1)

  buglist = sys.argv[1]
  template = sys.argv[2]

  global fixed, listfixed
  fixed = len(sys.argv) >= 4
  listfixed = {}

  if fixed:
    with open(sys.argv[3], 'r') as file:
      for line in file:
        parts = line.split(maxsplit=1)
        package = parts[0]
        version = parts[1].strip()
        listfixed[package] = version

  report_directory = os.path.join(os.environ["HOME"], "bugs-to-send")

  os.makedirs(report_directory, exist_ok=True)

  with open(buglist, 'r') as file:
    for line in file:
      if line.startswith('#'):
        continue
      parts = line.split(maxsplit=1)
      package = parts[0]
      subject = parts[1].strip()
      bug(package, template, subject, report_directory)


def bug(package, template, subject, report_directory):
  global fixed, listfixed

  debfullname = os.environ.get("DEBFULLNAME", "Somebody")
  debemail = os.environ.get("DEBEMAIL", "somebody@example.org")
  xdebbugscc = debemail

  email = f"{debfullname} <{debemail}>"

  tags = "ftbfs forky sid"
  severity = "serious"

  original_log = max(glob.glob(f"{package}_*"), key=os.path.getmtime)

  log = []

  user = ""
  usertags = ""

  addline = False

  with open(original_log, encoding="utf-8", errors="replace") as f:
    content = f.read()

  # case 1: unmet build-dependencies
  if re.search("E: Package build dependencies not satisfied; skipping", content):
    addline = True
    startre = "Install main build dependencies"
    endre = "Not removing build depends:"
  # case 2: failure in build target
  elif re.search("debian/rules build" , content):
    startre = "debian/rules build"
    endre = "Build finished at"
  # case 3: failure in clean target
  else:
    startre = "debian/rules clean"
    endre = "Build finished at"

  status = 0
  with open(original_log, encoding="utf-8", errors="replace") as f:
    for line in f:
      if status == 0 and line.startswith("Package:"):
        source = line.split()[1]
        status = 1
      elif status == 1 and line.startswith("Version:"):
        version = line.split()[1]
        status = 2
      elif status == 2 and re.search(startre, line):
        status = 3
        log.append(line)
      elif status == 3 and re.search(endre, line):
        if addline:
          log.append("-" * 80 + "\n")
        break
      elif status == 3:
        log.append(line)

    # subject without "FTBFS: "
    reduced_subject = re.escape(subject[7:])

    eureka = False
    if any(re.search(reduced_subject, line) for line in log):
      state = 0
      count = 0
      kept = []
      for line in reversed(log):
        kept.append(line)
        if state == 0:
          if re.search(reduced_subject, line):
            state = 1
        elif state == 1:
          count += 1
          if count == 5:
            log = list(reversed(kept))
            eureka = True
            break

  with open(template) as t:
    template = jinja2.Template(t.read(), keep_trailing_newline=True)

  if fixed:
    fixedversion = listfixed.get(source, "")
    tags = "ftbfs trixie"

  vars = {
    'email': email,
    'subject': subject,
    'source': source,
    'version': version,
    'severity': severity,
    'tags': tags,
    'log': ''.join(log),
    'user': user,
    'usertags': usertags
  }

  try:
    vars['fixedversion'] = fixedversion
  except:
    pass

  try:
    vars['xdebbugscc'] = xdebbugscc
  except:
    pass

  report_file = os.path.join(report_directory, original_log)
  if eureka:
    with open(report_file, 'w') as f:
      f.write(template.render(vars))
      print(f"Created {original_log}")

if __name__ == "__main__":
  main()
