#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Minify the translation messages.

These files don't need to be readable when shipped as no one looks at them
directly, and there's a bunch of metadata that are only for translators.
"""

from __future__ import print_function

import argparse
import json
import re
import sys


def minify_placeholders(msg):
    """Expand placeholder values where possible.

    An example input object:
      {
        "message": "Unable to parse destination: $DEST$",
        "placeholders": {
          "dest": {
            "content": "$1",
            "example": "invalid.destination"
          }
        }
      }

    We want to replace '$DEST$' in the message with '$1'.

    For more complicated replacements, we'll leave it alone (for now).
      {
        "message": "Goodbye, $USER$. Come back to $OUR_SITE$ soon!",
        "placeholders": {
          "our_site": {
            "content": "Example.com",
          }
        }
      }
    """
    assert 'message' in msg

    # Walk each of the placeholders.
    for key, settings in list(msg.get('placeholders', {}).items()):
        # Throw away the 'example' field which is meant for translators.
        settings.pop('example', None)

        # If the replacement is simple, inline it.
        m = re.match(r'^[$][0-9]+$', settings['content'])
        if m:
            msg['message'] = re.sub(r'[$]%s[$]' % (key,), settings['content'],
                                    msg['message'], flags=re.I)
            msg['placeholders'].pop(key)

    # Remove the placeholders setting if it's empty after we've processed it.
    placeholders = msg.get('placeholders', {})
    if not placeholders:
        msg.pop('placeholders', None)


def minify(path, inplace=False):
    """Minify translation."""
    with open(path) as fp:
        try:
            data = json.loads(fp.read())
        except ValueError as e:
            print('ERROR: Processing %s: %s' % (path, e), file=sys.stderr)
            return False

    # Strip out the metadata that only translators read.
    for msg in data.values():
        # Translator-aimed description of the message.
        msg.pop('description', None)

        # Expand the placeholders where possible.
        minify_placeholders(msg)

    # Throw away all whitespace.
    formatted = json.dumps(data, ensure_ascii=False, indent=None,
                           separators=(',', ':'))

    if inplace:
        with open(path, 'w') as fp:
            fp.write(formatted)
    else:
        sys.stdout.write(formatted + '\n')

    return True


def get_parser():
    """Get a command line parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-i', '--inplace', default=False, action='store_true',
                        help='Modify files inline rather than writing stdout.')
    parser.add_argument('files', nargs='+', metavar='files',
                        help='The translations to format.')
    return parser


def main(argv):
    """The main func!"""
    parser = get_parser()
    opts = parser.parse_args(argv)

    ret = 0
    for path in opts.files:
        if not minify(path, opts.inplace):
            ret = 1
    return ret


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