#!/usr/bin/env python
# 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_entity_to_uchar_array(entity):
    return "{'%s'}" % "', '".join(entity)


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.
 *
 * 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 "core/html/parser/HTMLEntityTable.h"

namespace WebCore {

namespace {
""")

for entry in entries:
    output_file.write("static const UChar %s[] = %s;\n" % (
        convert_entity_to_cpp_name(entry[ENTITY]),
        convert_entity_to_uchar_array(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)
