#!/usr/bin/env python
# Copyright 2015, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function

from argparse import ArgumentParser, FileType, Action
from hashlib import sha1
from os import fstat
import re
from struct import pack


BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096

def filesize(f):
    if f is None:
        return 0
    try:
        return fstat(f.fileno()).st_size
    except OSError:
        return 0


def update_sha(sha, f):
    if f:
        sha.update(f.read())
        f.seek(0)
        sha.update(pack('I', filesize(f)))
    else:
        sha.update(pack('I', 0))


def pad_file(f, padding):
    pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)
    f.write(pack(str(pad) + 'x'))


def get_number_of_pages(image_size, page_size):
    """calculates the number of pages required for the image"""
    return (image_size + page_size - 1) / page_size


def get_recovery_dtbo_offset(args):
    """calculates the offset of recovery_dtbo image in the boot image"""
    num_header_pages = 1 # header occupies a page
    num_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize)
    num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk), args.pagesize)
    num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize)
    dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages +
                                   num_ramdisk_pages + num_second_pages)
    return dtbo_offset


def write_header_v3(args):
    BOOT_IMAGE_HEADER_V3_SIZE = 1580
    BOOT_MAGIC = 'ANDROID!'.encode()

    args.output.write(pack('8s', BOOT_MAGIC))
    args.output.write(pack(
        '4I',
        filesize(args.kernel),                          # kernel size in bytes
        filesize(args.ramdisk),                         # ramdisk size in bytes
        (args.os_version << 11) | args.os_patch_level,  # os version and patch level
        BOOT_IMAGE_HEADER_V3_SIZE))

    args.output.write(pack('4I', 0, 0, 0, 0))           # reserved

    args.output.write(pack('I', args.header_version))   # version of bootimage header
    args.output.write(pack('1536s', args.cmdline.encode()))
    pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)

def write_vendor_boot_header(args):
    VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
    BOOT_MAGIC = 'VNDRBOOT'.encode()

    args.vendor_boot.write(pack('8s', BOOT_MAGIC))
    args.vendor_boot.write(pack(
        '5I',
        args.header_version,                            # version of header
        args.pagesize,                                  # flash page size we assume
        args.base + args.kernel_offset,                 # kernel physical load addr
        args.base + args.ramdisk_offset,                # ramdisk physical load addr
        filesize(args.vendor_ramdisk)))                 # vendor ramdisk size in bytes
    args.vendor_boot.write(pack('2048s', args.vendor_cmdline.encode()))
    args.vendor_boot.write(pack('I', args.base + args.tags_offset)) # physical addr for kernel tags
    args.vendor_boot.write(pack('16s', args.board.encode())) # asciiz product name
    args.vendor_boot.write(pack('I', VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) # header size in bytes
    if filesize(args.dtb) == 0:
        raise ValueError("DTB image must not be empty.")
    args.vendor_boot.write(pack('I', filesize(args.dtb)))   # size in bytes
    args.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
    pad_file(args.vendor_boot, args.pagesize)

def write_header(args):
    BOOT_IMAGE_HEADER_V1_SIZE = 1648
    BOOT_IMAGE_HEADER_V2_SIZE = 1660
    BOOT_MAGIC = 'ANDROID!'.encode()

    if args.header_version > 3:
        raise ValueError('Boot header version %d not supported' % args.header_version)
    elif args.header_version == 3:
        return write_header_v3(args)

    args.output.write(pack('8s', BOOT_MAGIC))
    final_ramdisk_offset = (args.base + args.ramdisk_offset) if filesize(args.ramdisk) > 0 else 0
    final_second_offset = (args.base + args.second_offset) if filesize(args.second) > 0 else 0
    args.output.write(pack(
        '10I',
        filesize(args.kernel),                          # size in bytes
        args.base + args.kernel_offset,                 # physical load addr
        filesize(args.ramdisk),                         # size in bytes
        final_ramdisk_offset,                           # physical load addr
        filesize(args.second),                          # size in bytes
        final_second_offset,                            # physical load addr
        args.base + args.tags_offset,                   # physical addr for kernel tags
        args.pagesize,                                  # flash page size we assume
        args.header_version,                            # version of bootimage header
        (args.os_version << 11) | args.os_patch_level)) # os version and patch level
    args.output.write(pack('16s', args.board.encode())) # asciiz product name
    args.output.write(pack('512s', args.cmdline[:512].encode()))

    sha = sha1()
    update_sha(sha, args.kernel)
    update_sha(sha, args.ramdisk)
    update_sha(sha, args.second)

    if args.header_version > 0:
        update_sha(sha, args.recovery_dtbo)
    if args.header_version > 1:
        update_sha(sha, args.dtb)

    img_id = pack('32s', sha.digest())

    args.output.write(img_id)
    args.output.write(pack('1024s', args.cmdline[512:].encode()))

    if args.header_version > 0:
        args.output.write(pack('I', filesize(args.recovery_dtbo)))   # size in bytes
        if args.recovery_dtbo:
            args.output.write(pack('Q', get_recovery_dtbo_offset(args))) # recovery dtbo offset
        else:
            args.output.write(pack('Q', 0)) # Will be set to 0 for devices without a recovery dtbo

    # Populate boot image header size for header versions 1 and 2.
    if args.header_version == 1:
        args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE))
    elif args.header_version == 2:
        args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE))

    if args.header_version > 1:

        if filesize(args.dtb) == 0:
            raise ValueError("DTB image must not be empty.")

        args.output.write(pack('I', filesize(args.dtb)))   # size in bytes
        args.output.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
    pad_file(args.output, args.pagesize)
    return img_id


class ValidateStrLenAction(Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if 'maxlen' not in kwargs:
            raise ValueError('maxlen must be set')
        self.maxlen = int(kwargs['maxlen'])
        del kwargs['maxlen']
        super(ValidateStrLenAction, self).__init__(option_strings, dest, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        if len(values) > self.maxlen:
            raise ValueError(
                'String argument too long: max {0:d}, got {1:d}'.format(self.maxlen, len(values)))
        setattr(namespace, self.dest, values)


def write_padded_file(f_out, f_in, padding):
    if f_in is None:
        return
    f_out.write(f_in.read())
    pad_file(f_out, padding)


def parse_int(x):
    return int(x, 0)


def parse_os_version(x):
    match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)
    if match:
        a = int(match.group(1))
        b = c = 0
        if match.lastindex >= 2:
            b = int(match.group(2))
        if match.lastindex == 3:
            c = int(match.group(3))
        # 7 bits allocated for each field
        assert a < 128
        assert b < 128
        assert c < 128
        return (a << 14) | (b << 7) | c
    return 0


def parse_os_patch_level(x):
    match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x)
    if match:
        y = int(match.group(1)) - 2000
        m = int(match.group(2))
        # 7 bits allocated for the year, 4 bits for the month
        assert 0 <= y < 128
        assert 0 < m <= 12
        return (y << 4) | m
    return 0


def parse_cmdline():
    parser = ArgumentParser()
    parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))
    parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
    parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
    parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))
    recovery_dtbo_group = parser.add_mutually_exclusive_group()
    recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',
                                     type=FileType('rb'))
    recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',
                                     type=FileType('rb'), metavar='RECOVERY_ACPIO',
                                     dest='recovery_dtbo')
    parser.add_argument('--cmdline', help='extra arguments to be passed on the '
                        'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
    parser.add_argument('--vendor_cmdline',
                        help='kernel command line arguments contained in vendor boot',
                        default='', action=ValidateStrLenAction, maxlen=2048)
    parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
    parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
    parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,
                        default=0x01000000)
    parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
                        default=0x00f00000)
    parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)

    parser.add_argument('--os_version', help='operating system version', type=parse_os_version,
                        default=0)
    parser.add_argument('--os_patch_level', help='operating system patch level',
                        type=parse_os_patch_level, default=0)
    parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)
    parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
                        maxlen=16)
    parser.add_argument('--pagesize', help='page size', type=parse_int,
                        choices=[2**i for i in range(11, 15)], default=2048)
    parser.add_argument('--id', help='print the image ID on standard output',
                        action='store_true')
    parser.add_argument('--header_version', help='boot image header version', type=parse_int,
                        default=0)
    parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))
    parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))
    parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))

    return parser.parse_args()


def write_data(args, pagesize):
    write_padded_file(args.output, args.kernel, pagesize)
    write_padded_file(args.output, args.ramdisk, pagesize)
    write_padded_file(args.output, args.second, pagesize)

    if args.header_version > 0 and args.header_version < 3:
        write_padded_file(args.output, args.recovery_dtbo, pagesize)
    if args.header_version == 2:
        write_padded_file(args.output, args.dtb, pagesize)


def write_vendor_boot_data(args):
    write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)
    write_padded_file(args.vendor_boot, args.dtb, args.pagesize)


def main():
    args = parse_cmdline()
    if args.vendor_boot is not None:
        if args.header_version < 3:
            raise ValueError('--vendor_boot not compatible with given header version')
        if args.vendor_ramdisk is None:
            raise ValueError('--vendor_ramdisk missing or invalid')
        write_vendor_boot_header(args)
        write_vendor_boot_data(args)
    if args.output is not None:
        if args.kernel is None:
            raise ValueError('kernel must be supplied when creating a boot image')
        if args.second is not None and args.header_version > 2:
            raise ValueError('--second not compatible with given header version')
        img_id = write_header(args)
        if args.header_version > 2:
            write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)
        else:
            write_data(args, args.pagesize)
        if args.id and img_id is not None:
            # Python 2's struct.pack returns a string, but py3 returns bytes.
            if isinstance(img_id, str):
                img_id = [ord(x) for x in img_id]
            print('0x' + ''.join('{:02x}'.format(c) for c in img_id))


if __name__ == '__main__':
    main()
