#! /usr/bin/env python3

"""pygettext -- Python equivalent of xgettext(1)

Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
internationalization of C programs. Most of these tools are independent of
the programming language and can be used from within Python programs.
Martin von Loewis' work[1] helps considerably in this regard.

pygettext uses Python's standard tokenize module to scan Python source
code, generating .pot files identical to what GNU xgettext[2] generates
for C and C++ code. From there, the standard GNU tools can be used.

A word about marking Python strings as candidates for translation. GNU
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
and gettext_noop. But those can be a lot of text to include all over your
code. C and C++ have a trick: they use the C preprocessor. Most
internationalized C source includes a #define for gettext() to _() so that
what has to be written in the source is much less. Thus these are both
translatable strings:

    gettext("Translatable String")
    _("Translatable String")

Python of course has no preprocessor so this doesn't work so well.  Thus,
pygettext searches only for _() by default, but see the -k/--keyword flag
below for how to augment this.

 [1] https://www.python.org/workshops/1997-10/proceedings/loewis.html
 [2] https://www.gnu.org/software/gettext/gettext.html

NOTE: pygettext attempts to be option and feature compatible with GNU
xgettext where ever possible. However some options are still missing or are
not fully implemented. Also, xgettext's use of command line switches with
option arguments is broken, and in these cases, pygettext just defines
additional switches.

NOTE: The public interface of pygettext is limited to the command-line
interface only. The internal API is subject to change without notice.

Usage: pygettext [options] inputfile ...

Options:

    -a
    --extract-all
        Deprecated: Not implemented and will be removed in a future version.

    -cTAG
    --add-comments=TAG
        Extract translator comments.  Comments must start with TAG and
        must precede the gettext call.  Multiple -cTAG options are allowed.
        In that case, any comment matching any of the TAGs will be extracted.

    -d name
    --default-domain=name
        Rename the default output file from messages.pot to name.pot.

    -E
    --escape
        Replace non-ASCII characters with octal escape sequences.

    -D
    --docstrings
        Extract module, class, method, and function docstrings.  These do
        not need to be wrapped in _() markers, and in fact cannot be for
        Python to consider them docstrings. (See also the -X option).

    -h
    --help
        Print this help message and exit.

    -k word
    --keyword=word
        Keywords to look for in addition to the default set, which are:
        _, gettext, ngettext, pgettext, npgettext, dgettext, dngettext,
        dpgettext, and dnpgettext.

        You can have multiple -k flags on the command line.

    -K
    --no-default-keywords
        Disable the default set of keywords (see above).  Any keywords
        explicitly added with the -k/--keyword option are still recognized.

    --no-location
        Do not write filename/lineno location comments.

    -n
    --add-location
        Write filename/lineno location comments indicating where each
        extracted string is found in the source.  These lines appear before
        each msgid.  The style of comments is controlled by the -S/--style
        option.  This is the default.

    -o filename
    --output=filename
        Rename the default output file from messages.pot to filename.  If
        filename is `-' then the output is sent to standard out.

    -p dir
    --output-dir=dir
        Output files will be placed in directory dir.

    -S stylename
    --style stylename
        Specify which style to use for location comments.  Two styles are
        supported:

        Solaris  # File: filename, line: line-number
        GNU      #: filename:line

        The style name is case insensitive.  GNU style is the default.

    -v
    --verbose
        Print the names of the files being processed.

    -V
    --version
        Print the version of pygettext and exit.

    -w columns
    --width=columns
        Set width of output to columns.

    -x filename
    --exclude-file=filename
        Specify a file that contains a list of strings that are not be
        extracted from the input files.  Each string to be excluded must
        appear on a line by itself in the file.

    -X filename
    --no-docstrings=filename
        Specify a file that contains a list of files (one per line) that
        should not have their docstrings extracted.  This is only useful in
        conjunction with the -D option above.

If `inputfile' is -, standard input is read.
"""

import ast
import getopt
import glob
import importlib.machinery
import importlib.util
import os
import sys
import time
import tokenize
from dataclasses import dataclass, field
from io import BytesIO
from operator import itemgetter

__version__ = '1.5'


# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
# there.
pot_header = '''\
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\\n"
"POT-Creation-Date: %(time)s\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: LANGUAGE <LL@li.org>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=%(charset)s\\n"
"Content-Transfer-Encoding: %(encoding)s\\n"
"Generated-By: pygettext.py %(version)s\\n"

'''


def usage(code, msg=''):
    print(__doc__, file=sys.stderr)
    if msg:
        print(msg, file=sys.stderr)
    sys.exit(code)


def make_escapes(pass_nonascii):
    global escapes, escape
    if pass_nonascii:
        # Allow non-ascii characters to pass through so that e.g. 'msgid
        # "Höhe"' would not result in 'msgid "H\366he"'.  Otherwise we
        # escape any character outside the 32..126 range.
        escape = escape_ascii
    else:
        escape = escape_nonascii
    escapes = [fr"\{i:03o}" for i in range(256)]
    for i in range(32, 127):
        escapes[i] = chr(i)
    escapes[ord('\\')] = r'\\'
    escapes[ord('\t')] = r'\t'
    escapes[ord('\r')] = r'\r'
    escapes[ord('\n')] = r'\n'
    escapes[ord('\"')] = r'\"'


def escape_ascii(s, encoding):
    return ''.join(escapes[ord(c)] if ord(c) < 128 else c
                   if c.isprintable() else escape_nonascii(c, encoding)
                   for c in s)


def escape_nonascii(s, encoding):
    return ''.join(escapes[b] for b in s.encode(encoding))


def normalize(s, encoding):
    # This converts the various Python string types into a format that is
    # appropriate for .po files, namely much closer to C style.
    lines = s.split('\n')
    if len(lines) == 1:
        s = '"' + escape(s, encoding) + '"'
    else:
        if not lines[-1]:
            del lines[-1]
            lines[-1] = lines[-1] + '\n'
        for i in range(len(lines)):
            lines[i] = escape(lines[i], encoding)
        lineterm = '\\n"\n"'
        s = '""\n"' + lineterm.join(lines) + '"'
    return s


def containsAny(str, set):
    """Check whether 'str' contains ANY of the chars in 'set'"""
    return 1 in [c in str for c in set]


def getFilesForName(name):
    """Get a list of module files for a filename, a module or package name,
    or a directory.
    """
    if not os.path.exists(name):
        # check for glob chars
        if containsAny(name, "*?[]"):
            files = glob.glob(name)
            list = []
            for file in files:
                list.extend(getFilesForName(file))
            return list

        # try to find module or package
        try:
            spec = importlib.util.find_spec(name)
            name = spec.origin
        except ImportError:
            name = None
        if not name:
            return []

    if os.path.isdir(name):
        # find all python files in directory
        list = []
        # get extension for python source files
        _py_ext = importlib.machinery.SOURCE_SUFFIXES[0]
        for root, dirs, files in os.walk(name):
            # don't recurse into CVS directories
            if 'CVS' in dirs:
                dirs.remove('CVS')
            # add all *.py files to list
            list.extend(
                [os.path.join(root, file) for file in files
                 if os.path.splitext(file)[1] == _py_ext]
                )
        return list
    elif os.path.exists(name):
        # a single file
        return [name]

    return []


# Key is the function name, value is a dictionary mapping argument positions to the
# type of the argument. The type is one of 'msgid', 'msgid_plural', or 'msgctxt'.
DEFAULTKEYWORDS = {
    '_': {'msgid': 0},
    'gettext': {'msgid': 0},
    'ngettext': {'msgid': 0, 'msgid_plural': 1},
    'pgettext': {'msgctxt': 0, 'msgid': 1},
    'npgettext': {'msgctxt': 0, 'msgid': 1, 'msgid_plural': 2},
    'dgettext': {'msgid': 1},
    'dngettext': {'msgid': 1, 'msgid_plural': 2},
    'dpgettext': {'msgctxt': 1, 'msgid': 2},
    'dnpgettext': {'msgctxt': 1, 'msgid': 2, 'msgid_plural': 3},
}


def parse_spec(spec):
    """Parse a keyword spec string into a dictionary.

    The keyword spec format defines the name of the gettext function and the
    positions of the arguments that correspond to msgid, msgid_plural, and
    msgctxt. The format is as follows:

        name - the name of the gettext function, assumed to
               have a single argument that is the msgid.
        name:pos1 - the name of the gettext function and the position
                    of the msgid argument.
        name:pos1,pos2 - the name of the gettext function and the positions
                         of the msgid and msgid_plural arguments.
        name:pos1,pos2c - the name of the gettext function and the positions
                          of the msgid and msgctxt arguments.
        name:pos1,pos2,pos3c - the name of the gettext function and the
                               positions of the msgid, msgid_plural, and
                               msgctxt arguments.

    As an example, the spec 'foo:1,2,3c' means that the function foo has three
    arguments, the first one is the msgid, the second one is the msgid_plural,
    and the third one is the msgctxt. The positions are 1-based.

    The msgctxt argument can appear in any position, but it can only appear
    once. For example, the keyword specs 'foo:3c,1,2' and 'foo:1,2,3c' are
    equivalent.

    See https://www.gnu.org/software/gettext/manual/gettext.html
    for more information.
    """
    parts = spec.strip().split(':', 1)
    if len(parts) == 1:
        name = parts[0]
        return name, {'msgid': 0}

    name, args = parts
    if not args:
        raise ValueError(f'Invalid keyword spec {spec!r}: '
                         'missing argument positions')

    result = {}
    for arg in args.split(','):
        arg = arg.strip()
        is_context = False
        if arg.endswith('c'):
            is_context = True
            arg = arg[:-1]

        try:
            pos = int(arg) - 1
        except ValueError as e:
            raise ValueError(f'Invalid keyword spec {spec!r}: '
                             'position is not an integer') from e

        if pos < 0:
            raise ValueError(f'Invalid keyword spec {spec!r}: '
                             'argument positions must be strictly positive')

        if pos in result.values():
            raise ValueError(f'Invalid keyword spec {spec!r}: '
                             'duplicate positions')

        if is_context:
            if 'msgctxt' in result:
                raise ValueError(f'Invalid keyword spec {spec!r}: '
                                 'msgctxt can only appear once')
            result['msgctxt'] = pos
        elif 'msgid' not in result:
            result['msgid'] = pos
        elif 'msgid_plural' not in result:
            result['msgid_plural'] = pos
        else:
            raise ValueError(f'Invalid keyword spec {spec!r}: '
                             'too many positions')

    if 'msgid' not in result and 'msgctxt' in result:
        raise ValueError(f'Invalid keyword spec {spec!r}: '
                         'msgctxt cannot appear without msgid')

    return name, result


def unparse_spec(name, spec):
    """Unparse a keyword spec dictionary into a string."""
    if spec == {'msgid': 0}:
        return name

    parts = []
    for arg, pos in sorted(spec.items(), key=lambda x: x[1]):
        if arg == 'msgctxt':
            parts.append(f'{pos + 1}c')
        else:
            parts.append(str(pos + 1))
    return f'{name}:{','.join(parts)}'


def process_keywords(keywords, *, no_default_keywords):
    custom_keywords = {}
    for spec in dict.fromkeys(keywords):
        name, spec = parse_spec(spec)
        if name not in custom_keywords:
            custom_keywords[name] = []
        custom_keywords[name].append(spec)

    if no_default_keywords:
        return custom_keywords

    # custom keywords override default keywords
    for name, spec in DEFAULTKEYWORDS.items():
        if name not in custom_keywords:
            custom_keywords[name] = []
        if spec not in custom_keywords[name]:
            custom_keywords[name].append(spec)
    return custom_keywords


@dataclass(frozen=True)
class Location:
    filename: str
    lineno: int

    def __lt__(self, other):
        return (self.filename, self.lineno) < (other.filename, other.lineno)


@dataclass
class Message:
    msgid: str
    msgid_plural: str | None
    msgctxt: str | None
    locations: set[Location] = field(default_factory=set)
    is_docstring: bool = False
    comments: list[str] = field(default_factory=list)

    def add_location(self, filename, lineno, msgid_plural=None, *,
                     is_docstring=False, comments=None):
        if self.msgid_plural is None:
            self.msgid_plural = msgid_plural
        self.locations.add(Location(filename, lineno))
        self.is_docstring |= is_docstring
        if comments:
            self.comments.extend(comments)


def get_source_comments(source):
    """
    Return a dictionary mapping line numbers to
    comments in the source code.
    """
    comments = {}
    for token in tokenize.tokenize(BytesIO(source).readline):
        if token.type == tokenize.COMMENT:
            # Remove any leading combination of '#' and whitespace
            comment = token.string.lstrip('# \t')
            comments[token.start[0]] = comment
    return comments


class GettextVisitor(ast.NodeVisitor):
    def __init__(self, options):
        super().__init__()
        self.options = options
        self.filename = None
        self.messages = {}
        self.comments = {}

    def visit_file(self, source, filename):
        try:
            module_tree = ast.parse(source)
        except SyntaxError:
            return

        self.filename = filename
        if self.options.comment_tags:
            self.comments = get_source_comments(source)
        self.visit(module_tree)

    def visit_Module(self, node):
        self._extract_docstring(node)
        self.generic_visit(node)

    visit_ClassDef = visit_FunctionDef = visit_AsyncFunctionDef = visit_Module

    def visit_Call(self, node):
        self._extract_message(node)
        self.generic_visit(node)

    def _extract_docstring(self, node):
        if (not self.options.docstrings or
            self.options.nodocstrings.get(self.filename)):
            return

        docstring = ast.get_docstring(node)
        if docstring is not None:
            lineno = node.body[0].lineno  # The first statement is the docstring
            self._add_message(lineno, docstring, is_docstring=True)

    def _extract_message(self, node):
        func_name = self._get_func_name(node)
        errors = []
        specs = self.options.keywords.get(func_name, [])
        for spec in specs:
            err = self._extract_message_with_spec(node, spec)
            if err is None:
                return
            errors.append(err)

        if not errors:
            return
        if len(errors) == 1:
            print(f'*** {self.filename}:{node.lineno}: {errors[0]}',
                  file=sys.stderr)
        else:
            # There are multiple keyword specs for the function name and
            # none of them could be extracted. Print a general error
            # message and list the errors for each keyword spec.
            print(f'*** {self.filename}:{node.lineno}: '
                  f'No keywords matched gettext call "{func_name}":',
                  file=sys.stderr)
            for spec, err in zip(specs, errors, strict=True):
                unparsed = unparse_spec(func_name, spec)
                print(f'\tkeyword="{unparsed}": {err}', file=sys.stderr)

    def _extract_message_with_spec(self, node, spec):
        """Extract a gettext call with the given spec.

        Return None if the gettext call was successfully extracted,
        otherwise return an error message.
        """
        max_index = max(spec.values())
        has_var_positional = any(isinstance(arg, ast.Starred) for
                                 arg in node.args[:max_index+1])
        if has_var_positional:
            return ('Variable positional arguments are not '
                    'allowed in gettext calls')

        if max_index >= len(node.args):
            return (f'Expected at least {max_index + 1} positional '
                    f'argument(s) in gettext call, got {len(node.args)}')

        msg_data = {}
        for arg_type, position in spec.items():
            arg = node.args[position]
            if not self._is_string_const(arg):
                return (f'Expected a string constant for argument '
                        f'{position + 1}, got {ast.unparse(arg)}')
            msg_data[arg_type] = arg.value

        lineno = node.lineno
        comments = self._extract_comments(node)
        self._add_message(lineno, **msg_data, comments=comments)

    def _extract_comments(self, node):
        """Extract translator comments.

        Translator comments must precede the gettext call and
        start with one of the comment prefixes defined by
        --add-comments=TAG. See the tests for examples.
        """
        if not self.options.comment_tags:
            return []

        comments = []
        lineno = node.lineno - 1
        # Collect an unbroken sequence of comments starting from
        # the line above the gettext call.
        while lineno >= 1:
            comment = self.comments.get(lineno)
            if comment is None:
                break
            comments.append(comment)
            lineno -= 1

        # Find the first translator comment in the sequence and
        # return all comments starting from that comment.
        comments = comments[::-1]
        first_index = next((i for i, comment in enumerate(comments)
                            if self._is_translator_comment(comment)), None)
        if first_index is None:
            return []
        return comments[first_index:]

    def _is_translator_comment(self, comment):
        return comment.startswith(self.options.comment_tags)

    def _add_message(
            self, lineno, msgid, msgid_plural=None, msgctxt=None, *,
            is_docstring=False, comments=None):
        if msgid in self.options.toexclude:
            return

        if not comments:
            comments = []

        key = self._key_for(msgid, msgctxt)
        message = self.messages.get(key)
        if message:
            message.add_location(
                self.filename,
                lineno,
                msgid_plural,
                is_docstring=is_docstring,
                comments=comments,
            )
        else:
            self.messages[key] = Message(
                msgid=msgid,
                msgid_plural=msgid_plural,
                msgctxt=msgctxt,
                locations={Location(self.filename, lineno)},
                is_docstring=is_docstring,
                comments=comments,
            )

    @staticmethod
    def _key_for(msgid, msgctxt=None):
        if msgctxt is not None:
            return (msgctxt, msgid)
        return msgid

    def _get_func_name(self, node):
        match node.func:
            case ast.Name(id=id):
                return id
            case ast.Attribute(attr=attr):
                return attr
            case _:
                return None

    def _is_string_const(self, node):
        return isinstance(node, ast.Constant) and isinstance(node.value, str)

def write_pot_file(messages, options, fp):
    timestamp = time.strftime('%Y-%m-%d %H:%M%z')
    encoding = fp.encoding if fp.encoding else 'UTF-8'
    print(pot_header % {'time': timestamp, 'version': __version__,
                        'charset': encoding,
                        'encoding': '8bit'}, file=fp)

    # Sort locations within each message by filename and lineno
    sorted_keys = [
        (key, sorted(msg.locations))
        for key, msg in messages.items()
    ]
    # Sort messages by locations
    # For example, a message with locations [('test.py', 1), ('test.py', 2)] will
    # appear before a message with locations [('test.py', 1), ('test.py', 3)]
    sorted_keys.sort(key=itemgetter(1))

    for key, locations in sorted_keys:
        msg = messages[key]

        for comment in msg.comments:
            print(f'#. {comment}', file=fp)

        if options.writelocations:
            # location comments are different b/w Solaris and GNU:
            if options.locationstyle == options.SOLARIS:
                for location in locations:
                    print(f'# File: {location.filename}, line: {location.lineno}', file=fp)
            elif options.locationstyle == options.GNU:
                # fit as many locations on one line, as long as the
                # resulting line length doesn't exceed 'options.width'
                locline = '#:'
                for location in locations:
                    s = f' {location.filename}:{location.lineno}'
                    if len(locline) + len(s) <= options.width:
                        locline = locline + s
                    else:
                        print(locline, file=fp)
                        locline = f'#:{s}'
                if len(locline) > 2:
                    print(locline, file=fp)
        if msg.is_docstring:
            # If the entry was gleaned out of a docstring, then add a
            # comment stating so.  This is to aid translators who may wish
            # to skip translating some unimportant docstrings.
            print('#, docstring', file=fp)
        if msg.msgctxt is not None:
            print('msgctxt', normalize(msg.msgctxt, encoding), file=fp)
        print('msgid', normalize(msg.msgid, encoding), file=fp)
        if msg.msgid_plural is not None:
            print('msgid_plural', normalize(msg.msgid_plural, encoding), file=fp)
            print('msgstr[0] ""', file=fp)
            print('msgstr[1] ""\n', file=fp)
        else:
            print('msgstr ""\n', file=fp)


def main():
    try:
        opts, args = getopt.getopt(
            sys.argv[1:],
            'ac::d:DEhk:Kno:p:S:Vvw:x:X:',
            ['extract-all', 'add-comments=?', 'default-domain=', 'escape',
             'help', 'keyword=', 'no-default-keywords',
             'add-location', 'no-location', 'output=', 'output-dir=',
             'style=', 'verbose', 'version', 'width=', 'exclude-file=',
             'docstrings', 'no-docstrings',
             ])
    except getopt.error as msg:
        usage(1, msg)

    # for holding option values
    class Options:
        # constants
        GNU = 1
        SOLARIS = 2
        # defaults
        extractall = 0 # FIXME: currently this option has no effect at all.
        escape = 0
        keywords = []
        outpath = ''
        outfile = 'messages.pot'
        writelocations = 1
        locationstyle = GNU
        verbose = 0
        width = 78
        excludefilename = ''
        docstrings = 0
        nodocstrings = {}
        comment_tags = set()

    options = Options()
    locations = {'gnu' : options.GNU,
                 'solaris' : options.SOLARIS,
                 }
    no_default_keywords = False
    # parse options
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage(0)
        elif opt in ('-a', '--extract-all'):
            print("DeprecationWarning: -a/--extract-all is not implemented and will be removed in a future version",
                  file=sys.stderr)
            options.extractall = 1
        elif opt in ('-c', '--add-comments'):
            options.comment_tags.add(arg)
        elif opt in ('-d', '--default-domain'):
            options.outfile = arg + '.pot'
        elif opt in ('-E', '--escape'):
            options.escape = 1
        elif opt in ('-D', '--docstrings'):
            options.docstrings = 1
        elif opt in ('-k', '--keyword'):
            options.keywords.append(arg)
        elif opt in ('-K', '--no-default-keywords'):
            no_default_keywords = True
        elif opt in ('-n', '--add-location'):
            options.writelocations = 1
        elif opt in ('--no-location',):
            options.writelocations = 0
        elif opt in ('-S', '--style'):
            options.locationstyle = locations.get(arg.lower())
            if options.locationstyle is None:
                usage(1, f'Invalid value for --style: {arg}')
        elif opt in ('-o', '--output'):
            options.outfile = arg
        elif opt in ('-p', '--output-dir'):
            options.outpath = arg
        elif opt in ('-v', '--verbose'):
            options.verbose = 1
        elif opt in ('-V', '--version'):
            print(f'pygettext.py (xgettext for Python) {__version__}')
            sys.exit(0)
        elif opt in ('-w', '--width'):
            try:
                options.width = int(arg)
            except ValueError:
                usage(1, f'--width argument must be an integer: {arg}')
        elif opt in ('-x', '--exclude-file'):
            options.excludefilename = arg
        elif opt in ('-X', '--no-docstrings'):
            fp = open(arg)
            try:
                while 1:
                    line = fp.readline()
                    if not line:
                        break
                    options.nodocstrings[line[:-1]] = 1
            finally:
                fp.close()

    options.comment_tags = tuple(options.comment_tags)

    # calculate escapes
    make_escapes(not options.escape)

    # calculate all keywords
    try:
        options.keywords = process_keywords(
            options.keywords,
            no_default_keywords=no_default_keywords)
    except ValueError as e:
        print(e, file=sys.stderr)
        sys.exit(1)

    # initialize list of strings to exclude
    if options.excludefilename:
        try:
            with open(options.excludefilename) as fp:
                options.toexclude = fp.readlines()
        except OSError:
            print(f"Can't read --exclude-file: {options.excludefilename}",
                  file=sys.stderr)
            sys.exit(1)
    else:
        options.toexclude = []

    # resolve args to module lists
    expanded = []
    for arg in args:
        if arg == '-':
            expanded.append(arg)
        else:
            expanded.extend(getFilesForName(arg))
    args = expanded

    # slurp through all the files
    visitor = GettextVisitor(options)
    for filename in args:
        if filename == '-':
            if options.verbose:
                print('Reading standard input')
            source = sys.stdin.buffer.read()
        else:
            if options.verbose:
                print(f'Working on {filename}')
            with open(filename, 'rb') as fp:
                source = fp.read()

        visitor.visit_file(source, filename)

    # write the output
    if options.outfile == '-':
        fp = sys.stdout
        closep = 0
    else:
        if options.outpath:
            options.outfile = os.path.join(options.outpath, options.outfile)
        fp = open(options.outfile, 'w')
        closep = 1
    try:
        write_pot_file(visitor.messages, options, fp)
    finally:
        if closep:
            fp.close()


if __name__ == '__main__':
    main()
