#!/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.

"""Crush image files.

We try to shrink the image files by reencoding/stripping data losslessly.

We currently support png and jpg files.
"""

from __future__ import print_function

import argparse
import base64
import glob
import logging
import multiprocessing
import os
import subprocess
import sys

import requests

import libdot


# We pick a recent Chromium commit.  It doesn't change much so shouldn't matter.
# Updating to the latest version shouldn't cause problems.
CHROMIUM_REF = '69.0.3460.0'

# Full path to Chromium's png crush script.
PNG_CRUSHER_URL = 'https://chromium.googlesource.com/chromium/src/+/%s/tools/resources/optimize-png-files.sh' % (CHROMIUM_REF,)

# Our local cache of the script.
PNG_CRUSHER = os.path.join(libdot.BIN_DIR, '.png.crusher.%s' % (CHROMIUM_REF,))

# The tool used to crush jpeg images.
JPG_CRUSHER = 'jpegoptim'


def update_png_crusher():
    """Update our local cache of Chromium's png optimizer script."""
    if os.path.exists(PNG_CRUSHER):
        return

    for path in glob.glob(os.path.join(libdot.BIN_DIR, '.png.crusher.*')):
        os.unlink(path)

    r = requests.get(PNG_CRUSHER_URL + '?format=TEXT')
    with open(PNG_CRUSHER, 'wb') as fp:
        fp.write(base64.b64decode(r.text))

    os.chmod(PNG_CRUSHER, 0o755)


def run(path, cmd):
    logging.info('Processing %s', path)
    logging.debug('Running: %s', ' '.join(cmd))
    subprocess.call(cmd)


def process_file(pool, path):
    """Crush |path| as makes sense.

    Jobs are thrown into the |pool|, but we don't currently bother checking
    their return values.  General life cycle management is handled by the pool.
    """
    _, ext = os.path.splitext(path)
    if ext in ('.png',):
        update_png_crusher()
        pool.apply_async(run, (path, [PNG_CRUSHER, path]))
    elif ext in ('.jpg', '.jpeg'):
        pool.apply_async(run, (path, [JPG_CRUSHER, path]))


def process_dir(pool, path):
    """Process all the paths under |path|."""
    for root, dirs, files in os.walk(path):
        # Not really needed, but makes things consistent.
        dirs.sort()
        files.sort()

        for path in files:
            process_file(pool, os.path.join(root, path))


def get_parser():
    """Get a command line parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-d', '--debug', action='store_true',
                        help='Run with debug output.')
    parser.add_argument('paths', nargs='+',
                        help='Image files or directories to crush.')
    return parser


def main(argv):
    parser = get_parser()
    opts = parser.parse_args(argv)
    libdot.setup_logging(debug=opts.debug)

    pool = multiprocessing.Pool()

    # We walk the top set of args by hand to deref links.
    for path in opts.paths:
        if os.path.isdir(path):
            process_dir(pool, path)
        elif os.path.isfile(path):
            process_file(pool, path)

    pool.close()
    pool.join()


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