#!/usr/bin/env python3

import json
import subprocess
import shutil
import os
import sys
import re
import glob
import argparse

parser = argparse.ArgumentParser(description='Create APT repo.')
parser.add_argument('dists', metavar='DIST', nargs='+')
args = parser.parse_args()

projects=json.load(open("projects.json"))

filedir="/tmp/debian-control-files/repos-files/"
aptpool=projects["AptPool"]
apt=aptpool+"/.."

os.makedirs(filedir, exist_ok=True)

keyDebFileRegex = re.compile("^(.*/)?([^_]*)_[^_]*_([a-z0-9]*)[.]deb$")
def keyDebFile(f):
  try:
    m = keyDebFileRegex.search(f)
    return m.group(2)+":"+m.group(3)
  except:
    return f

def getPackagesFromDsc(f):
  res=[]
  start=False
  for l in open(f).readlines():
    if l.startswith("Package-List:"):
      start=True
    elif start and ":" in l:
      start=False
    elif start:
      res.append(l.strip().split(" ")[0])
  assert(res!=[])
  # print("getPackagesFromDsc(%s)->%s" % (f,res))
  return res



for target in ["nightly","stable","release"]:
  for dist in args.dists:
    print(dist,target)
    for arch in ["binary-i386", "binary-amd64", "binary-armhf", "binary-arm64", "source"]:
      d ="%s/../dists/%s/%s/%s" % (aptpool,dist,target,arch)
      if not os.path.exists(d):
        os.makedirs(d)
    distfiles=("%s/%s-%s" % (filedir,dist,target))
    distsources=("%s/%s-%s.source" % (filedir,dist,target))
    distsourceslst=["# Automatically generated file"]
    try:
      lines=[l.strip() for l in open(distfiles).readlines() if not 'pool/libraries' in l]
    except:
      lines=[]
    debfileshash = {}
    for l in lines:
      debfileshash[keyDebFile(l)] = l
    debfileshash["# Automatically generated file"] = "# Automatically generated file"
    for project in projects["Projects"]:
      p=projects["Projects"][project]
      rev=p[target]
      dscFile = "%s/contrib/%s_%s-1.dsc" % (aptpool, project.lower(), rev)
      dsc=getPackagesFromDsc(dscFile)
      if os.path.exists(dscFile):
        distsourceslst.append(dscFile.replace(aptpool,"pool"))
      for p in dsc:
        globstr = "%s/contrib-%s/%s_%s-1_*.deb" % (aptpool, dist, p, rev)
        # print(globstr)
        for f in glob.glob(globstr):
          f=f.replace(aptpool, "pool")
          debfileshash[keyDebFile(f)] = f
    debfiles="\n".join(sorted(debfileshash.values()))
    open(distfiles,"w").write(debfiles)
    open(distsources,"w").write("\n".join(sorted(distsourceslst)))

for dist in args.dists:
  open("%s/apt-%s.conf" % (filedir,dist), "w").write("""
APT::FTPArchive::Release::Codename "%s";
APT::FTPArchive::Release::Origin "openmodelica.org";
APT::FTPArchive::Release::Components "nightly stable release";
APT::FTPArchive::Release::Label "OpenModelica Repository";
APT::FTPArchive::Release::Architectures "amd64 i386 armhf arm64 source";
APT::FTPArchive::Release::Suite "%s";
""" % (dist,dist))
  for target in ["nightly","stable","release"]:
    print(dist,target)
    filetarget="%s/%s-%s" % (filedir,dist,target)
    conf = open(filetarget+".conf","w").write("""
Dir {
 ArchiveDir ".";
 CacheDir "./.cache";
};

Default {
 Packages::Compress ". gzip bzip2";
 Contents::Compress ". gzip bzip2";
 Sources::Compress ". gzip bzip2";
};

TreeDefault {
 BinCacheDB "packages-$(SECTION)-$(ARCH).db";
 Packages "$(DIST)/$(SECTION)/binary-$(ARCH)/Packages";
 Sources "$(DIST)/$(SECTION)/source/Sources";
 Contents "$(DIST)/Contents-$(ARCH)";
};

Tree "dists/%s" {
 Sections "%s";
 Architectures "i386 amd64 armhf arm64 source";
 FileList "%s";
 SourceFileList "%s.source";
}
""" % (dist,target,filetarget,filetarget))

    assert(0==subprocess.call(["bash", "-c", 'cd %s && apt-ftparchive generate "%s/%s-%s.conf" 2> /tmp/apt-build-omc.log && apt-ftparchive sources "%s/%s-%s.conf" 2>> /tmp/apt-build-omc.log' % (apt,filedir,dist,target,filedir,dist,target)]))
    subprocess.call(["grep", "-v", "has no [a-z]* override entry", "/tmp/apt-build-omc.log"])

  assert(0==subprocess.call(["bash", "-c", 'cd %s && apt-ftparchive -c "%s/apt-%s.conf" release %s/dists/%s 2>&1 > /tmp/apt-build-Release' % (aptpool,filedir,dist,apt,dist)]))
  with open("/tmp/apt-build-Release") as fin:
    with open("%s/dists/%s/Release" % (apt,dist), "w") as fout:
      fout.write(fin.read())
  try:
    os.remove("%s/dists/%s/Release.gpg" % (apt,dist))
  except:
    pass
  assert(0==subprocess.call(["gpg", "--batch=yes", "-abs", "-o", "%s/dists/%s/Release.gpg" % (apt,dist), "%s/dists/%s/Release" % (apt,dist)]))
