#!/usr/bin/env python3
# Copyright (c) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import csv
import os.path
import string
import sys

ENTITY = 0
VALUE = 1

def convert_entity_to_cpp_name(entity):
    postfix = "EntityName"
    if entity[-1] == ";":
        return "%sSemicolon%s" % (entity[:-1], postfix)
    return "%s%s" % (entity, postfix)


def convert_value_to_int(value):
    if not value:
        return "0";
    assert(value[0] == "U")
    assert(value[1] == "+")
    return "0x" + value[2:]


def offset_table_entry(offset):
    return "    &staticEntityTable[%s]," % offset


program_name = os.path.basename(__file__)
if len(sys.argv) < 4 or sys.argv[1] != "-o":
    # Python 3, change to: print("Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name, file=sys.stderr)
    sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name)
    exit(1)

output_path = sys.argv[2]
input_path = sys.argv[3]

html_entity_names_file = open(input_path)
entries = list(csv.reader(html_entity_names_file))
html_entity_names_file.close()

entries.sort(key = lambda entry: entry[ENTITY])
entity_count = len(entries)

output_file = open(output_path, "w")

output_file.write("""/*
 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
 * Copyright (C) 2013 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

// THIS FILE IS GENERATED BY WebCore/html/parser/create-html-entity-table
// DO NOT EDIT (unless you are a ninja)!

#include "config.h"
#include "HTMLEntityTable.h"

namespace WebCore {

namespace {
""")

for entry in entries:
    output_file.write("static const LChar %s[] = \"%s\";\n" % (convert_entity_to_cpp_name(entry[ENTITY]), entry[ENTITY]))

output_file.write("""
static const HTMLEntityTableEntry staticEntityTable[%s] = {\n""" % entity_count)

index = {}
offset = 0
for entry in entries:
    letter = entry[ENTITY][0]
    if letter not in index:
        index[letter] = offset
    values = entry[VALUE].split(' ')
    assert len(values) <= 2, values
    output_file.write('    { %s, %s, %s, %s },\n' % (
        convert_entity_to_cpp_name(entry[ENTITY]),
        len(entry[ENTITY]),
        convert_value_to_int(values[0]),
        convert_value_to_int(values[1] if len(values) >= 2 else "")))
    offset += 1

output_file.write("""};

""")

output_file.write("static const HTMLEntityTableEntry* uppercaseOffset[] = {\n")
for letter in string.ascii_uppercase:
    output_file.write("%s\n" % offset_table_entry(index[letter]))
output_file.write("%s\n" % offset_table_entry(index['a']))
output_file.write("""};

static const HTMLEntityTableEntry* lowercaseOffset[] = {\n""")
for letter in string.ascii_lowercase:
    output_file.write("%s\n" % offset_table_entry(index[letter]))
output_file.write("%s\n" % offset_table_entry(entity_count))
output_file.write("""};

}

const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
{
    if (c >= 'A' && c <= 'Z')
        return uppercaseOffset[c - 'A'];
    if (c >= 'a' && c <= 'z')
        return lowercaseOffset[c - 'a'];
    return 0;
}

const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
{
    if (c >= 'A' && c <= 'Z')
        return uppercaseOffset[c - 'A' + 1] - 1;
    if (c >= 'a' && c <= 'z')
        return lowercaseOffset[c - 'a' + 1] - 1;
    return 0;
}

const HTMLEntityTableEntry* HTMLEntityTable::firstEntry()
{
    return &staticEntityTable[0];
}

const HTMLEntityTableEntry* HTMLEntityTable::lastEntry()
{
    return &staticEntityTable[%s - 1];
}

}
""" % entity_count)
