#!/usr/bin/env python3
# Copyright (C) 2022 Igalia S.L.
# Copyright (C) 2022 Red Hat Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

import argparse
import os
import sys

VALID_EXTENSIONS = {'.html', '.js', '.css', '.svg', '.png', '.gif', '.cur', '.bcmap', '.properties', '.pfb', '.ttf'}
COMPRESSIBLE_EXTENSIONS = {'.html', '.js', '.css', '.svg', '.properties'}
BASE_DIRS = {'pdfjs/', 'pdfjs-extras/'}

IGNORE = {'LICENSE',
          'PdfJSFiles.cmake',
          'README.webkit',
          'web/cmaps/LICENSE',
          'web/standard_fonts/LICENSE_FOXIT',
          'web/standard_fonts/LICENSE_LIBERATION'}


def get_filenames(directory):
    filenames = []

    def resource_name(filename):
        for base_directory in BASE_DIRS:
            base_dir_index = filename.rfind(base_directory)
            if base_dir_index != -1:
                return filename[base_dir_index + len(base_directory):]
        return None

    for root, dirs, files in os.walk(directory):
        dirs.sort()
        files.sort()
        for file in files:
            # FIXME: Find a more sophisticated way to ignore unwanted
            # port-specific files, so this will work for Cocoa ports too.
            if os.path.basename(root) == 'cocoa':
                continue
            filename = os.path.join(root, file)
            name = resource_name(filename)
            if name is None:
                continue

            # The result should use forward slashes, thus make sure any os-specific
            # separator is properly replaced.
            if os.sep != '/':
                name = name.replace(os.sep, '/')
            if name not in IGNORE:
                if os.path.splitext(name)[1] not in VALID_EXTENSIONS:
                    print('Unexpected file %s, please teach generate-pdfjs-resource-manifest.py how to handle it' % filename, file=sys.stderr)
                    sys.exit(1)
                filenames.append(name)

    return filenames


def is_compressible(filename):
    return os.path.splitext(filename)[1] in COMPRESSIBLE_EXTENSIONS


def write_cmake_file(args):
    args.output.write("# This file was generated by Tools/glib/generate-pdfjs-resource-manifest.py. Do not modify manually.\n")
    args.output.write('set(PDFJSFiles\n')
    for filename in get_filenames(args.input):
        args.output.write('    ${THIRDPARTY_DIR}/pdfjs/%s\n' % filename)
    args.output.write(')')


def write_gresource_manifest(args):
    args.output.write("""<?xml version=1.0 encoding=UTF-8?>
<gresources>
    <gresource prefix="/org/webkit/pdfjs">
""")

    for filename in get_filenames(args.input):
        line = '        <file'
        if is_compressible(filename):
            line += ' compressed="true"'
        if not filename.startswith('build/') and not filename.startswith('web/'):
            alias = 'extras/' + filename
            line += ' alias="%s"' % alias
        line += '>%s</file>\n' % filename

        args.output.write(line)

    args.output.write("""    </gresource>
</gresources>
""")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Generate a GResources file for pdfjs.')
    parser.add_argument('--input', type=str,
                        help='the input directory')
    parser.add_argument('--output', nargs='?', type=argparse.FileType('w'), default=sys.stdout,
                        help='the output file')
    parser.add_argument('--cmake', action='store_true',
                        help='generate CMake file list')
    parser.add_argument('--gresource', action='store_true',
                        help='generate GResource manifest')

    args = parser.parse_args(sys.argv[1:])

    if args.cmake and args.gresource:
        print('Cannot pass both --cmake and --gresource at the same time', file=sys.stderr)
        sys.exit(1)
    elif args.cmake:
        write_cmake_file(args)
    elif args.gresource:
        write_gresource_manifest(args)
    else:
        print('Must pass either --cmake or --gresource', file=sys.stderr)
        sys.exit(1)
