#!/usr/bin/env python3

# Copyright 2017-2021 The Meson development team
#
# 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 subprocess
import shutil, sys, os

import xml.etree.ElementTree as ET

sys.path.append(os.getcwd())
from mesonbuild import coredata

from createmsi import get_modules

class PkgGenerator:

    def __init__(self):
        self.pkg_dir = 'macpkg'
        self.sharedir = os.path.join(self.pkg_dir, 'usr/local/share')
        self.bindir = os.path.join(self.pkg_dir, 'usr/local/bin')
        self.product_name = 'Meson Build System'
        self.identifier = 'com.mesonbuild.meson'
        self.version = coredata.version.replace('dev', '')
        self.mesonstashdir = os.path.join(self.sharedir, f'meson-{self.version}')
        self.pkgname = 'meson.pkg'
        self.productname = f'meson-{self.version}.pkg'
        self.distribution_file = 'meson-distribution.xml'
        self.resourcedir = 'packaging/macpages'

    def build_dist(self):
        if os.path.exists(self.pkg_dir):
            shutil.rmtree(self.pkg_dir)
        os.mkdir(self.pkg_dir)
        pyinstaller_bin = '/Users/jpakkane/Library/Python/3.8/bin/pyinstaller'
        pyinst_cmd = [pyinstaller_bin,
                      '--clean',
                      '--distpath',
                      self.pkg_dir]
        for m in get_modules():
            pyinst_cmd += ['--hidden-import', m]
        pyinst_cmd += ['meson.py']
        subprocess.check_call(pyinst_cmd)
        tmpdir = os.path.join(self.pkg_dir, 'meson')
        shutil.move(tmpdir, self.mesonstashdir)
        os.makedirs(self.bindir)
        ln_base = os.path.relpath(self.mesonstashdir, self.bindir)
        ninja_bin = shutil.which('ninja')
        assert ninja_bin
        shutil.copy(ninja_bin, self.bindir)
        subprocess.check_call(['strip', os.path.join(self.bindir, 'ninja')])
        os.symlink(os.path.join(ln_base, 'meson'), os.path.join(self.bindir, 'meson'))

    def build_package(self):
        subprocess.check_call(['pkgbuild',
                               '--root',
                               self.pkg_dir,
                               '--identifier',
                               self.identifier,
                               self.pkgname])
        self.generate_distribution()
        subprocess.check_call(['productbuild',
                               '--distribution',
                               self.distribution_file,
                               '--resources',
                               self.resourcedir,
                               self.productname])

    def generate_distribution(self):
        root = ET.Element('installer-gui-script', {'minSpecVersion': '1'})
        ET.SubElement(root, 'welcome', {'file': 'welcome.html',
                                        'mime-type': 'text/html'})
        ET.SubElement(root, 'license', {'file': 'license.html',
                                        'mime-type': 'text/html'})
        ET.SubElement(root, 'conclusion', {'file': 'conclusion.html',
                                        'mime-type': 'text/html'})
        ET.SubElement(root, 'pkg-ref', {'id': self.identifier})
        ET.SubElement(root, 'options', {'customize': 'never',
                                        'require-scripts': 'false',
                                        'hostArhcitectures': 'x86_64,arm64'})
        choices_outline = ET.SubElement(root, 'choices-outline')
        line = ET.SubElement(choices_outline, 'line', {'choice': 'default'})
        ET.SubElement(line, 'line', {'choice': self.identifier})
        ET.SubElement(root, 'choice', {'id': 'default'})
        choice = ET.SubElement(root, 'choice', {'id': self.identifier, 'visible': 'false'})
        ET.SubElement(choice, 'pkg-ref', {'id': self.identifier})
        ET.SubElement(root, 'pkg-ref', {'id': self.identifier,
                                        'version': '0', # self.version,
                                        'onConclusion': 'none'}).text = self.pkgname
        ET.ElementTree(root).write(self.distribution_file, encoding='utf-8', xml_declaration=True)
        # ElementTree can not do prettyprinting so do it manually
        import xml.dom.minidom
        doc = xml.dom.minidom.parse(self.distribution_file)
        with open(self.distribution_file, 'w') as open_file:
            open_file.write(doc.toprettyxml())

    def remove_tempfiles(self):
        shutil.rmtree('macpkg')
        os.unlink('meson-distribution.xml')
        os.unlink('meson.pkg')
        os.unlink('meson.spec')

if __name__ == '__main__':
    if not os.path.exists('meson.py'):
        sys.exit(print('Run me in the top level source dir.'))
    subprocess.check_call(['pip3', 'install', '--user', '--upgrade', 'pyinstaller'])

    pg = PkgGenerator()
    pg.build_dist()
    pg.build_package()
    pg.remove_tempfiles()
