'''
Inspect the header of ereader files. This is primarily used for debugging.
'''


__license__   = 'GPL v3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'

import struct
import sys

from calibre.ebooks.pdb.ereader import EreaderError
from calibre.ebooks.pdb.header import PdbHeaderReader


def ereader_header_info(header):
    h0 = header.section_data(0)

    print('Header Size:     %s' % len(h0))

    if len(h0) == 132:
        print('Header Type:     Dropbook compatible')
        print('')
        ereader_header_info132(h0)
    elif len(h0) == 202:
        print('Header Type:     Makebook compatible')
        print('')
        ereader_header_info202(h0)
    else:
        raise EreaderError('Size mismatch. eReader header record size %i KB is not supported.' % len(h0))


def pdb_header_info(header):
    print('PDB Header Info:')
    print('')
    print('Identity:        %s' % header.ident)
    print('Total Sections:   %s' % header.num_sections)
    print('Title:           %s' % header.title)
    print('')


def ereader_header_info132(h0):
    print('Ereader Record 0 (Header) Info:')
    print('')
    print('0-2 Version:             %i' % struct.unpack('>H', h0[0:2])[0])
    print('2-4:                     %i' % struct.unpack('>H', h0[2:4])[0])
    print('4-6:                     %i' % struct.unpack('>H', h0[4:6])[0])
    print('6-8 Codepage:            %i' % struct.unpack('>H', h0[6:8])[0])
    print('8-10:                    %i' % struct.unpack('>H', h0[8:10])[0])
    print('10-12:                   %i' % struct.unpack('>H', h0[10:12])[0])
    print('12-14 Non-Text offset:   %i' % struct.unpack('>H', h0[12:14])[0])
    print('14-16:                   %i' % struct.unpack('>H', h0[14:16])[0])
    print('16-18:                   %i' % struct.unpack('>H', h0[16:18])[0])
    print('18-20:                   %i' % struct.unpack('>H', h0[18:20])[0])
    print('20-22 Image Count:       %i' % struct.unpack('>H', h0[20:22])[0])
    print('22-24:                   %i' % struct.unpack('>H', h0[22:24])[0])
    print('24-26 Has Metadata?:     %i' % struct.unpack('>H', h0[24:26])[0])
    print('26-28:                   %i' % struct.unpack('>H', h0[26:28])[0])
    print('28-30 Footnote Count:    %i' % struct.unpack('>H', h0[28:30])[0])
    print('30-32 Sidebar Count:     %i' % struct.unpack('>H', h0[30:32])[0])
    print('32-34 Bookmark Offset:   %i' % struct.unpack('>H', h0[32:34])[0])
    print('34-36 MAGIC:             %i' % struct.unpack('>H', h0[34:36])[0])
    print('36-38:                   %i' % struct.unpack('>H', h0[36:38])[0])
    print('38-40:                   %i' % struct.unpack('>H', h0[38:40])[0])
    print('40-42 Image Data Offset: %i' % struct.unpack('>H', h0[40:42])[0])
    print('42-44:                   %i' % struct.unpack('>H', h0[42:44])[0])
    print('44-46 Metadata Offset:   %i' % struct.unpack('>H', h0[44:46])[0])
    print('46-48:                   %i' % struct.unpack('>H', h0[46:48])[0])
    print('48-50 Footnote Offset:   %i' % struct.unpack('>H', h0[48:50])[0])
    print('50-52 Sidebar Offset:    %i' % struct.unpack('>H', h0[50:52])[0])
    print('52-54 Last Data Offset:  %i' % struct.unpack('>H', h0[52:54])[0])

    for i in range(54, 131, 2):
        print('%i-%i:                   %i' % (i, i+2, struct.unpack('>H', h0[i:i+2])[0]))

    print('')


def ereader_header_info202(h0):
    print('Ereader Record 0 (Header) Info:')
    print('')
    print('0-2 Version:             %i' % struct.unpack('>H', h0[0:2])[0])
    print('2-4 Garbage:             %i' % struct.unpack('>H', h0[2:4])[0])
    print('4-6 Garbage:             %i' % struct.unpack('>H', h0[4:6])[0])
    print('6-8 Garbage:             %i' % struct.unpack('>H', h0[6:8])[0])
    print('8-10 Non-Text Offset:    %i' % struct.unpack('>H', h0[8:10])[0])
    print('10-12:                   %i' % struct.unpack('>H', h0[10:12])[0])
    print('12-14:                   %i' % struct.unpack('>H', h0[12:14])[0])
    print('14-16 Garbage:           %i' % struct.unpack('>H', h0[14:16])[0])
    print('16-18 Garbage:           %i' % struct.unpack('>H', h0[16:18])[0])
    print('18-20 Garbage:           %i' % struct.unpack('>H', h0[18:20])[0])
    print('20-22 Garbage:           %i' % struct.unpack('>H', h0[20:22])[0])
    print('22-24 Garbage:           %i' % struct.unpack('>H', h0[22:24])[0])
    print('24-26:                   %i' % struct.unpack('>H', h0[24:26])[0])
    print('26-28:                   %i' % struct.unpack('>H', h0[26:28])[0])
    for i in range(28, 98, 2):
        print('%i-%i Garbage:           %i' % (i, i+2, struct.unpack('>H', h0[i:i+2])[0]))
    print('98-100:                  %i' % struct.unpack('>H', h0[98:100])[0])
    for i in range(100, 110, 2):
        print('%i-%i Garbage:         %i' % (i, i+2, struct.unpack('>H', h0[i:i+2])[0]))
    print('110-112:                 %i' % struct.unpack('>H', h0[110:112])[0])
    print('112-114:                 %i' % struct.unpack('>H', h0[112:114])[0])
    print('114-116 Garbage:         %i' % struct.unpack('>H', h0[114:116])[0])
    for i in range(116, 202, 2):
        print('%i-%i:                 %i' % (i, i+2, struct.unpack('>H', h0[i:i+2])[0]))

    print('')
    print('* Garbage: Random values.')
    print('')


def section_lengths(header):
    print('Section Sizes')
    print('')

    for i in range(0, header.section_count()):
        size = len(header.section_data(i))
        if size > 65505:
            message = '<--- Over!'
        else:
            message = ''

        print('Section %i:   %i %s' % (i, size, message))


def main(args=sys.argv):
    if len(args) < 2:
        print('Error: requires input file.')
        return 1

    f = open(sys.argv[1], 'rb')

    pheader = PdbHeaderReader(f)

    pdb_header_info(pheader)
    ereader_header_info(pheader)
    section_lengths(pheader)

    return 0


if __name__ == '__main__':
    sys.exit(main())
