#!/usr/bin/env python
#
# Copyright 2017 Google Inc. All rights reserved.
#
# Licensed 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.

import argparse
import glob
import os
from os import path
import sys

"""Create aliases in target directory.

The target files should not contain the emoji variation selector
codepoint in their names."""

DATA_ROOT = path.dirname(path.abspath(__file__))

def str_to_seq(seq_str):
  return tuple([int(s, 16) for s in seq_str.split('_')])


def seq_to_str(seq):
  return '_'.join('%04x' % cp for cp in seq)


def read_default_unknown_flag_aliases():
  unknown_flag_path = path.join(DATA_ROOT, 'unknown_flag_aliases.txt')
  return read_emoji_aliases(unknown_flag_path)


def read_default_emoji_aliases():
  alias_path = path.join(DATA_ROOT, 'emoji_aliases.txt')
  return read_emoji_aliases(alias_path)


def read_emoji_aliases(filename):
  result = {}

  with open(filename, 'r') as f:
    for line in f:
      ix = line.find('#')
      if (ix > -1):
        line = line[:ix]
      line = line.strip()
      if not line:
        continue
      als, trg = (s.strip() for s in line.split(';'))
      try:
        als_seq = tuple([int(x, 16) for x in als.split('_')])
        trg_seq = tuple([int(x, 16) for x in trg.split('_')])
      except:
        print 'cannot process alias %s -> %s' % (als, trg)
        continue
      result[als_seq] = trg_seq
  return result


def add_aliases(filedir, prefix, ext, replace=False, dry_run=False):
  if not path.isdir(filedir):
    print >> sys.stderr, '%s is not a directory' % filedir
    return

  prefix_len = len(prefix)
  suffix_len = len(ext) + 1
  filenames = [path.basename(f)
               for f in glob.glob(path.join(filedir, '%s*.%s' % (prefix, ext)))]
  seq_to_file = {
      str_to_seq(name[prefix_len:-suffix_len]) : name
      for name in filenames}

  aliases = read_emoji_aliases()
  aliases_to_create = {}
  aliases_to_replace = []
  for als,trg in sorted(aliases.items()):
    if trg not in seq_to_file:
      print >> sys.stderr, 'target %s for %s does not exist' % (
          seq_to_str(trg), seq_to_str(als))
      continue
    if als in seq_to_file:
      if replace:
        aliases_to_replace.append(seq_to_file[als])
      else:
        print >> sys.stderr, 'alias %s exists' % seq_to_str(als)
        continue
    target_file = seq_to_file[trg]
    alias_name = '%s%s.%s' % (prefix, seq_to_str(als), ext)
    aliases_to_create[alias_name] = target_file

  if replace:
    if not dry_run:
      for k in sorted(aliases_to_replace):
        os.remove(path.join(filedir, k))
    print 'replacing %d files' % len(aliases_to_replace)

  for k, v in sorted(aliases_to_create.items()):
    if dry_run:
      msg = 'replace ' if k in aliases_to_replace else ''
      print '%s%s -> %s' % (msg, k, v)
    else:
      try:
        os.symlink(v, path.join(filedir, k))
      except:
        print >> sys.stderr, 'failed to create %s -> %s' % (k, v)
        raise Exception('oops')
  print 'created %d symlinks' % len(aliases_to_create)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-d', '--filedir', help='directory containing files to alias',
      required=True, metavar='dir')
  parser.add_argument(
      '-p', '--prefix', help='file name prefix (default emoji_u)',
      metavar='pfx', default='emoji_u')
  parser.add_argument(
      '-e', '--ext', help='file name extension (default png)',
      choices=['ai', 'png', 'sgv'], default='png')
  parser.add_argument(
      '-r', '--replace', help='replace existing files/aliases',
      action='store_true')
  parser.add_argument(
      '-n', '--dry_run', help='print out aliases to create only',
      action='store_true')
  args = parser.parse_args()

  add_aliases(args.filedir, args.prefix, args.ext, args.replace, args.dry_run)


if __name__ == '__main__':
  main()
