#!/usr/bin/python3
import re
import sys
import os
import posixpath
import zipfile
import argparse
import bs4
import requests

SANE_FILENAME_PATTERN = re.compile("^[a-zA-Z0-9_\.-]+$")
SINIT_PATTERN = re.compile("^.*sinit.*\.zip$", re.I)

def get_zip_url(url):
    zip_pattern = re.compile("^.*\.zip$")
    zip_link = {
        "data-href": lambda x: x is not None and zip_pattern.match(x)
    }
    r = requests.get(url)
    assert r.status_code == 200
    soup = bs4.BeautifulSoup(r.text, "lxml")
    for button in soup.findAll("button", zip_link):
        return button["data-href"]
    assert False

def get_available_downloads():
    download_pattern = re.compile("^/content/www/us/en/download/.*\.html$")
    url = "https://www.intel.com/content/www/us/en/developer/articles/tool/intel-trusted-execution-technology.html"
    r = requests.get(url)
    assert r.status_code == 200
    soup = bs4.BeautifulSoup(r.text, "lxml")
    download_link = {
        "href": lambda x: x is not None and download_pattern.match(x)
    }
    downloads = []
    for a in soup.findAll("a", download_link):
        details_url = "https://www.intel.com" + a["href"]
        zip_url = get_zip_url(details_url)
        downloads.append(zip_url)
    return downloads

def download_acms(urls, target_directory):
    if os.path.exists(target_directory):
        print("Target directory {target_directory} already exists".format(target_directory=target_directory))
        sys.exit(1)
    os.mkdir(target_directory)
    os.mkdir(os.path.join(target_directory, "acm"))
    for url in urls:
        filename = posixpath.basename(url)
        assert SANE_FILENAME_PATTERN.match(filename)
        r = requests.get(url)
        assert r.status_code == 200
        local_zip_filename = os.path.join(target_directory, "acm", filename)
        assert local_zip_filename.endswith(".zip")
        local_unpack_dir = local_zip_filename[:-4]
        with open(local_zip_filename, "wb+") as f:
            f.write(r.content)
        with zipfile.ZipFile(local_zip_filename, "r") as f:
            f.extractall(local_unpack_dir)
        os.unlink(local_zip_filename)

def main():
    parser = argparse.ArgumentParser("Download ACMs from Intel website")
    parser.add_argument("--output-directory", required=True, help="Target directory")
    args = parser.parse_args()

    sinit_filter = lambda x: SINIT_PATTERN.match(x)
    available_downloads = get_available_downloads()
    available_sinit_downloads = list(filter(sinit_filter, available_downloads))
    assert len(available_sinit_downloads) > 5

    download_acms(available_sinit_downloads, args.output_directory)

if __name__ == "__main__":
    main()
