#!/usr/bin/env python3

# Copyright (c) 2017 The ungoogled-chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

'''
This script takes in files and generates a platform ini as if they were uploaded to the Releases page

Output is to stdout, so consider redirecting the output to a file
'''

import sys
import pathlib
import hashlib
import collections

class DownloadsManager:
    _algorithms = ["md5", "sha1", "sha256"]
    _downloads = dict()
    _username = None
    _project = None
    _version = None

    @classmethod
    def set_params(cls, username, project, version):
        cls._username = username
        cls._project = project
        cls._version = version

    @classmethod
    def _create_download_url(cls, filename):
        return "https://github.com/{username}/{project}/releases/download/{version}/{filename}".format(
            filename=filename,
            version=cls._version,
            username=cls._username,
            project=cls._project)

    @classmethod
    def to_ini(cls):
        download_template = '''[{filename}]
url = {url}
{hashes}'''
        hash_template = '''{algorithm} = {filehash}'''

        downloads_list = list()
        for filename in sorted(cls._downloads):
            hashes_list = list()
            for algorithm in cls._downloads[filename]:
                hashes_list.append(hash_template.format(
                    algorithm=algorithm.lower(),
                    filehash=cls._downloads[filename][algorithm]))
            downloads_list.append(download_template.format(
                filename=filename,
                url=cls._create_download_url(filename),
                hashes="\n".join(hashes_list)))
        return "\n\n".join(downloads_list)

    @classmethod
    def add_download(self, filepath):
        if filepath.name in self._downloads:
            raise Exception("File {!s} already added".format(filepath))
        self._downloads[filepath.name] = dict()
        with filepath.open("rb") as fileobj:
            for algorithm in self._algorithms:
                hasher = hashlib.new(algorithm)
                hasher.update(fileobj.read())
                self._downloads[filepath.name][algorithm] = hasher.hexdigest()
                fileobj.seek(0)

def print_usage_info():
    print("\n".join([
        "Arguments: release_name github_user_or_organization_name github_project_name [file_name [file_name [...]]]",
        "",
        "This script outputs an INI file to standard output containing hashes and links to files from a GitHub Release.",
        "This script *cannot* be used to reference non-GitHub Release files.",
        "",
        "Argument descriptions:",
        "release_name is the name of the GitHub Release.",
        "github_user_or_organization_name and github_project_name specify the repository to use",
        "file_name are one or more paths to local files with the same name as the ones in the GitHub Release."
        ]), file=sys.stderr)

def main(args):
    print(args, file=sys.stderr)
    if args[0] == "--help" or args[0] == "-h" or args[0] == "help":
        print_usage_info()
        return 0
    args_parser = iter(args)
    current_version = next(args_parser)
    username = next(args_parser)
    project = next(args_parser)
    DownloadsManager.set_params(username, project, current_version)
    for filename in args_parser:
        DownloadsManager.add_download(pathlib.Path(filename))
    print(DownloadsManager.to_ini())
    return 0

if __name__ == "__main__":
    exit(main(sys.argv[1:]))

@@ -2455,37 +2455,35 @@
 ame 
-%5B
 file_
-name
+path
  %5Bfile_
-name
+path
  %5B...%5D%5D
-%5D
 %22,%0A 
@@ -2594,14 +2594,180 @@
 les 
-from a
+as if they were uploaded to a GitHub Release.%22,%0A        %22The files that are passed in are read to generate hashes. Also, their file names are assumed to be identical in the
  Git
@@ -2826,16 +2826,15 @@
  to 
-referenc
+generat
 e no
@@ -2854,16 +2854,20 @@
 ase file
+ URL
 s.%22,%0A   
@@ -3080,20 +3080,20 @@
   %22file_
-name
+path
  are one

Reword help message in platform_ini_generator.py