#!/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_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)
