#!/usr/bin/env python
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
'''python %(prog)s [options]
Generate mapping from IPP attribute name to appropriate handler based on its
type as described in IPP registration files.'''

import argparse
import csv
import re

# Skip attributes that are already implemented in print preview plus job-priority (b/172208667).
NOOP_ATTRS = [
    'copies',
    'job-hold-until',
    'job-copies',
    'job-password',
    'job-password-encryption',
    'job-priority',
    'media',
    'media-col',
    'multiple-document-handling',
    'number-up',
    'orientation-requested',
    'page-ranges',
    'presentation-direction-number-up',
    'print-color-mode',
    'print-scaling',
    'printer-resolution',
    'sheet-collate',
    'sides',
]

# RFC 8011 (5.1.4) requires keywords to start with a letter. There's however at
# least one keyword that starts with a digit.
KEYWORD_PATTERN = re.compile('^[a-z1-9][a-z0-9\._-]*$')

HANDLER_HEADER = """// DO NOT MODIFY
// Generated by printing/backend/tools/code_generator.py

#include "printing/backend/ipp_handler_map.h"

#include "base/functional/bind.h"
#include "printing/backend/ipp_handlers.h"

namespace printing {

HandlerMap GenerateHandlers() {
  HandlerMap result;
"""

HANDLER_FOOTER = """  return result;
}

}  // namespace printing
"""

L10N_HEADER = """// DO NOT MODIFY
// Generated by printing/backend/tools/code_generator.py

#include "chrome/common/printing/ipp_l10n.h"

#include "base/no_destructor.h"
#include "components/strings/grit/components_strings.h"

const std::map<base::StringPiece, int>& CapabilityLocalizationMap() {
  static const base::NoDestructor<std::map<base::StringPiece, int>> l10n_map({
"""

L10N_FOOTER = """  });
  return *l10n_map;
}
"""


def get_handler(syntax, name):
  if syntax.startswith('1setOf'):
    handler = get_handler(syntax[6:].strip(), name)
    if handler == 'EnumHandler':
      # 3 is 'none' value for finishings.
      # IPP enums always use positive numbers so we can use 0 in other cases.
      default = 3 if name.endswith('finishings') else 0
      return 'MultivalueEnumHandler, %d' % default

    # TODO(crbug.com/964919): Add other multivalue handlers.
    return ''

  if syntax == 'collection':
    # TODO(crbug.com/964919): Add collection handler.
    return ''

  if syntax.startswith('type1') or syntax.startswith('type2'):
    # ignore prefix
    return get_handler(syntax[5:].strip(), name)

  if syntax.startswith('keyword'):
    return 'KeywordHandler'

  if syntax.startswith('enum'):
    return 'EnumHandler'

  if syntax == 'boolean':
    return 'BooleanHandler'

  if syntax.startswith('integer'):
    # TODO(crbug.com/964919): Add integer handler.
    return 'NumberHandler'

  if syntax.startswith('name') or syntax.startswith('text'):
    return 'TextHandler'

  return ''


# Remove annotations like '(obsolete)', '(deprecated)' etc.
def remove_annotation(keyword):
  parenthesis = keyword.find('(')
  return keyword if parenthesis == -1 else keyword[:parenthesis].strip()


SPECIAL_CHARS = re.compile('[-/\.]')


def add_l10n(l10n_file, ipp_id, grit_id=None):
  if not grit_id:
    grit_id = ipp_id

  l10n_file.write('      {"%s", IDS_PRINT_%s},\n' %
                  (ipp_id, SPECIAL_CHARS.sub('_', grit_id.upper())))


def main():
  parser = argparse.ArgumentParser(usage=__doc__)
  parser.add_argument(
      '-a',
      '--attributes-file',
      dest='attributes_file',
      help='path to ipp-registrations-2.csv input file',
      metavar='FILE',
      required=True)
  parser.add_argument(
      '-k',
      '--keyword-values-file',
      dest='keyword_values_file',
      help='path to ipp-registrations-4.csv input file',
      metavar='FILE',
      required=True)
  parser.add_argument(
      '-e',
      '--enum-values-file',
      dest='enum_values_file',
      help='path to ipp-registrations-6.csv input file',
      metavar='FILE',
      required=True)
  parser.add_argument(
      '-i',
      '--ipp-handler-map',
      dest='ipp_handler_map',
      help='path to ipp_handler_map.cc output file',
      metavar='FILE')
  parser.add_argument(
      '-l',
      '--localization-map',
      dest='localization_map',
      help='path to ipp_l10n.cc output file',
      metavar='FILE')
  args = parser.parse_args()

  if not (args.ipp_handler_map or args.localization_map):
    parser.error('No output file selected')

  handlers = []
  supported_items = set()
  with open(args.attributes_file, 'r') as attr_file:
    attr_reader = csv.reader(attr_file)

    for attr in attr_reader:
      # Filter out by attribute group.
      if attr[0] != 'Job Template':
        continue

      # Skip sub-attributes.
      if attr[2] != '':
        continue

      attr_name = remove_annotation(attr[1])
      # Skip duplicates
      if attr_name in supported_items:
        continue

      if not KEYWORD_PATTERN.match(attr_name):
        print('Warning: attribute name %s is invalid' % attr_name)
        continue

      syntax = attr[4]
      handler = 'NoOpHandler'
      if attr_name not in NOOP_ATTRS:
        handler = get_handler(syntax.strip(), attr_name)

      if handler == '':
        continue

      handlers.append((attr_name, handler))
      if handler != 'NoOpHandler':
        supported_items.add(attr_name)

  if args.ipp_handler_map:
    handler_file = open(args.ipp_handler_map, 'w')
    handler_file.write(HANDLER_HEADER)

    for (attr_name, handler) in handlers:
      handler_file.write('  result.emplace("%s", base::BindRepeating(&%s));\n'
                         % (attr_name, handler))

    handler_file.write(HANDLER_FOOTER)
    handler_file.close()

  if args.localization_map:
    l10n_file = open(args.localization_map, 'w')
    l10n_file.write(L10N_HEADER)

    for (attr_name, handler) in handlers:
      if handler != 'NoOpHandler':
        if args.localization_map and not handler.startswith('Multivalue'):
          add_l10n(l10n_file, attr_name)

    # media-source is only handled for localization because it's inside of
    # the media-col collection and we don't handle collections otherwise.
    supported_items.add("media-source")
    add_l10n(l10n_file, "media-source")

    with open(args.keyword_values_file, 'r') as keyword_file:
      keyword_reader = csv.reader(keyword_file)
      for keyword_item in keyword_reader:
        attr_name = keyword_item[0]
        if attr_name in supported_items:
          keyword_value = remove_annotation(keyword_item[1])
          # TODO(crbug.com/964919): Also handle some plain English cases.
          if KEYWORD_PATTERN.match(keyword_value):
            l10n_key = '%s/%s' % (attr_name, keyword_value)
            # Skip duplicates.
            if l10n_key not in supported_items:
              supported_items.add(l10n_key)
              add_l10n(l10n_file, l10n_key)

    with open(args.enum_values_file, 'r') as enum_file:
      enum_reader = csv.reader(enum_file)
      for enum_item in enum_reader:
        attr_name = enum_item[0]
        if attr_name in supported_items:
          enum_value = enum_item[1]
          try:
            int(enum_value)
            l10n_key = attr_name + '/' + enum_value
            # Skip duplicates and finishings 'none' value.
            if l10n_key not in supported_items and l10n_key != 'finishings/3':
              supported_items.add(l10n_key)
              add_l10n(l10n_file, l10n_key,
                       attr_name + '_' + remove_annotation(enum_item[2]))
          except ValueError:
            # TODO(crbug.com/964919): Handle some plain English cases.
            pass

    l10n_file.write(L10N_FOOTER)
    l10n_file.close()


if __name__ == '__main__':
  main()
