#!/usr/bin/env python
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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.
#
#
# Script which generates a collage of provider logos from multiple provider
# logo files.
#
# It works in two steps:
#
# 1. Resize all the provider logo files (reduce the dimensions)
# 2. Assemble a final image from the resized images

import os
import sys
import argparse
import subprocess
import random

from os.path import join as pjoin

DIMENSIONS = '150x150'  # Dimensions of the resized image (<width>x<height>)
GEOMETRY = '+4+4'  # How to arrange images (+<rows>+<columns>)

TO_CREATE_DIRS = ['resized/', 'final/']


def setup(output_path):
    """
    Create missing directories.
    """
    for directory in TO_CREATE_DIRS:
        final_path = pjoin(output_path, directory)

        if not os.path.exists(final_path):
            os.makedirs(final_path)


def get_logo_files(input_path):
    logo_files = os.listdir(input_path)
    logo_files = [name for name in logo_files if
                  'resized' not in name and name.endswith('png')]
    logo_files = [pjoin(input_path, name) for name in logo_files]

    return logo_files


def resize_images(logo_files, output_path):
    resized_images = []

    for logo_file in logo_files:
        name, ext = os.path.splitext(os.path.basename(logo_file))
        new_name = '%s%s' % (name, ext)
        out_name = pjoin(output_path, 'resized/', new_name)

        print 'Resizing image: %(name)s' % {'name': logo_file}

        values = {'name': logo_file, 'out_name': out_name,
                  'dimensions': DIMENSIONS}
        cmd = 'convert %(name)s -resize %(dimensions)s %(out_name)s'
        cmd = cmd % values
        subprocess.call(cmd, shell=True)

        resized_images.append(out_name)

    return resized_images


def assemble_final_image(resized_images, output_path):
    final_name = pjoin(output_path, 'final/logos.png')
    random.shuffle(resized_images)
    values = {'images': ' '.join(resized_images), 'geometry': GEOMETRY,
              'out_name': final_name}
    cmd = 'montage %(images)s -geometry %(geometry)s %(out_name)s'
    cmd = cmd % values

    print 'Generating final image: %(name)s' % {'name': final_name}
    subprocess.call(cmd, shell=True)


def main(input_path, output_path):
    if not os.path.exists(input_path):
        print('Path doesn\'t exist: %s' % (input_path))
        sys.exit(2)

    if not os.path.exists(output_path):
        print('Path doesn\'t exist: %s' % (output_path))
        sys.exit(2)

    logo_files = get_logo_files(input_path=input_path)

    setup(output_path=output_path)
    resized_images = resize_images(logo_files=logo_files,
                                   output_path=output_path)
    assemble_final_image(resized_images=resized_images,
                         output_path=output_path)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Assemble provider logos '
                                                 ' in a single image')
    parser.add_argument('--input-path', action='store',
                        help='Path to directory which contains provider '
                             'logo files')
    parser.add_argument('--output-path', action='store',
                        help='Path where the new files will be written')
    args = parser.parse_args()

    input_path = os.path.abspath(args.input_path)
    output_path = os.path.abspath(args.output_path)

    main(input_path=input_path, output_path=output_path)
