#!/usr/bin/env python2
# Copyright 2017, 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
try:
	from os import fstat, stat, remove
	from sys import exit
	from argparse import ArgumentParser, FileType
	from ctypes import sizeof, Structure, c_char, c_int
	from struct import pack, calcsize
	import zlib
except Exception as e:
	print("some module is needed:" + str(e))
	exit(-1)

dt_head_info_fmt = '4sII'
dt_entry_fmt = 'Q4I2Q'
dtimg_version = 1
dtb_count = 1

def write32(output, value):
	output.write(chr(value & 255)) ; value=value // 256
	output.write(chr(value & 255)) ; value=value // 256
	output.write(chr(value & 255)) ; value=value // 256
	output.write(chr(value & 255))

def compress(filename, input, output):
	output.write('\037\213\010')
	output.write(chr(0))

	statval = stat(filename)
	write32(output, 0)
	output.write('\002')
	output.write('\003')

	crcval = zlib.crc32("")
	compobj = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS,
		zlib.DEF_MEM_LEVEL, 0)
	while True:
		data = input.read(1024)
		if data == "":
			break
		crcval = zlib.crc32(data, crcval)
		output.write(compobj.compress(data))
	output.write(compobj.flush())
	write32(output, crcval)
	write32(output, statval.st_size)

def dtb_compress(dtb_file):
	try:
		outputname = dtb_file + '.gz'
		input = open(dtb_file, 'rb')
		output = open(outputname, 'wb')
		compress(dtb_file, input, output)
		input.close()
		output.close()
	except Exception as e:
		print('dtb_compress error:' + str(e))
		exit(-1)
	return outputname

class dt_head_info(Structure):
	_fields_ = [('magic', c_char * 4),
		    ('version', c_int),
		    ('dt_count', c_int)]

class dt_entry_t(Structure):
	_fields_ = [('dtb_size', c_int),
		    ('dtb_offset', c_int)]

def align_page_size(offset, pagesize):
	return (pagesize - (offset % pagesize))

def write_head_info(head_info, args):
	args.output.write(pack(dt_head_info_fmt,
			       head_info.magic,
			       head_info.version,
			       head_info.dt_count))

def write_dtb_entry_t(dt_entry, args):
	args.output.write(pack(dt_entry_fmt,
			       0,  # reserved
			       dt_entry.dtb_size,
			       0,  # reserved
			       dt_entry.dtb_offset,
			       0,  # reserved
			       0,  # reserved
			       0)) # reserved

def write_padding(args, padding):
	for i in range(0, padding):
		args.output.write('\x00')

def write_dtb(args):
	dtb_file = args.dtb
	out_dtb = dtb_file
	if args.compress == True:
		out_dtb = dtb_compress(dtb_file)
	try:
		dtb_offset = calcsize(dt_head_info_fmt) + \
				      calcsize(dt_entry_fmt) + \
				      4
		padding = align_page_size(dtb_offset, args.pagesize)
		dtb_size = stat(out_dtb).st_size
		dtb_size_padding = align_page_size(dtb_size, args.pagesize)
		dt_entry = dt_entry_t(dtb_size + dtb_size_padding,
				      dtb_offset + padding)
		write_dtb_entry_t(dt_entry, args)
		args.output.write(pack('I', 0)) # SUCCESS code number
		write_padding(args, padding)
		with open(out_dtb, 'rb') as dtb_fd:
			args.output.write(dtb_fd.read(dtb_size))
			write_padding(args, dtb_size_padding)
	except Exception as e:
		print('write dtb error:' + str(e))
		exit(-1)

def clean_gz_file(args):
	try:
		if args.compress != True:
			return
		remove(args.dtb + '.gz')
	except Exception as e:
		print('clean gz file error:' + str(e))
		exit(-1)

def parse_cmdline():
	parser = ArgumentParser()
	parser.add_argument('-c', '--compress', help='compress dtb or not',
			    action='store_true')
	parser.add_argument('-d', '--dtb', help='path to the dtb', type=str,
			    required=True)
	parser.add_argument('-s', '--pagesize', help='align page size',
			    type=int, choices=[2**i for i in range(11,15)],
			    default=2048)
	parser.add_argument('-o', '--output', help='output file name',
			    type=FileType('wb'), required=True)
	return parser.parse_args()

def main():
	args = parse_cmdline()
	dtimg_head_info = dt_head_info('HSDT', dtimg_version, dtb_count)
	write_head_info(dtimg_head_info, args)
	write_dtb(args)
	clean_gz_file(args)

if __name__ == '__main__':
	main()
