import datetime
import textwrap
import base64

def _write_java_header(output, package):
    year = datetime.date.today().year
    output.write(
        "/*\n"
        " * Copyright (C) %(year)d The Android Open Source Project\n"
        " *\n"
        " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
        " * you may not use this file except in compliance with the License.\n"
        " * You may obtain a copy of the License at\n"
        " *\n"
        " *      http://www.apache.org/licenses/LICENSE-2.0\n"
        " *\n"
        " * Unless required by applicable law or agreed to in writing, software\n"
        " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
        " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
        " * See the License for the specific language governing permissions and\n"
        " * limitations under the License.\n"
        " */\n\n"
        "/* This file is generated by print_log_list.py\n"
        " * https://github.com/google/certificate-transparency/blob/master/python/utilities/log_list/print_log_list.py */\n\n"
        "package %(package)s;\n\n" %
        {"year": year,
         "package": package})

def _encode_key(description, key):
    unsigned = (ord(c) for c in key)
    signed = (u - 256 if u > 127 else u for u in unsigned)
    array = textwrap.fill(", ".join("%d" % s for s in signed),
                          width=85,
                          initial_indent="    " * 3,
                          subsequent_indent="    " * 3)

    return ("        // %(description)s\n"
            "        new byte[] {\n"
            "%(array)s\n"
            "        },\n" % {
                "description": description,
                "array": array
            })

def _write_java_class(output, logs, class_name):
    descriptions = ('        "%s",\n' % log["description"] for log in logs)
    urls = ('        "%s",\n' % log["url"] for log in logs)
    keys = (_encode_key(log["description"], base64.decodestring(log["key"]))
            for log in logs)

    output.write(
        "public final class %(class_name)s {\n"
        "    public static final int LOG_COUNT = %(count)d;\n"
        "    public static final String[] LOG_DESCRIPTIONS = new String[] {\n"
        "%(descriptions)s"
        "    };\n"
        "    public static final String[] LOG_URLS = new String[] {\n"
        "%(urls)s"
        "    };\n"
        "    public static final byte[][] LOG_KEYS = new byte[][] {\n"
        "%(keys)s"
        "    };\n"
        "}\n" % {
            "class_name": class_name,
            "count": len(logs),
            "descriptions": "".join(descriptions),
            "urls": "".join(urls),
            "keys": "".join(keys)
        })


def generate_java_source(json_log_list, output_path, class_name):
    with open(output_path, "w") as output:
        logs = json_log_list["logs"]

        [pkg, cls] = class_name.rsplit('.', 1)
        _write_java_header(output, pkg)
        _write_java_class(output, logs, cls)

