#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Part of pymzml test cases
"""
import os
from pymzml.utils.GSGW import GSGW
import unittest
import zlib
import struct


class GSGWTest(unittest.TestCase):
    '''
    TODO: Write messages for assertions
    '''
    def setUp(self):
        self.paths = [
            os.path.join(
                os.path.dirname(__file__),
                'data',
                'unittest.mzml'
            )
        ]
        self.Writer = GSGW(
            self.paths[0],
            max_idx        = 80,
            max_idx_len    = 8,
            max_offset_len = 8,
            output_path    = os.path.abspath(
                os.path.join(
                    '.',
                    'tests',
                    'data',
                    'unittest.mzml'
                    )
            )
        )

    def tearDown(self):
        """
        """
        self.Writer.close()
        os.remove(os.path.abspath(os.path.join('.','tests','data', 'unittest.mzml')))


    def test_init(self):
        self.assertEqual(self.Writer.crc32, 0)
        self.assertEqual(self.Writer.crc32, 0)
        self.assertEqual(
            self.Writer.file_name, 
            os.path.abspath(
                os.path.join(
                    # os.path.dirname(__file__),
                    # 'Test',
                    'tests',
                    'data',
                    'unittest.mzml'
                )
            )
        )

    def test_write_gen_header_index(self):
        self.Writer._write_gen_header(Index=True)
        self.Writer.close()
        file = open(self.paths[0], 'rb')
        header = file.read()
        file.close()

        # Normal stuff
        self.assertEqual(header[:2], b'\x1f\x8b') # Gzip magic bytes
        self.assertEqual(header[2], 8) # comp
        self.assertEqual(header[3], 16) # comment flags set
        # self.assertEqual(header[5:9], b'') # time, how to check?
        self.assertEqual(header[8], 2) # xfl
        self.assertEqual(header[9], 3) # os

        # extra field with index
        self.assertEqual(header[10:12], b'FU') # magic index bytes
        self.assertEqual(header[12], 1) # version

    def test_write_gen_header_no_index(self):
        self.Writer._write_gen_header(Index=False)
        self.Writer.close()
        file = open(self.paths[0], 'rb')
        header = file.read()
        file.close()
        # Normal stuff
        self.assertEqual(header[:2], b'\x1f\x8b')
        self.assertEqual(header[2], 8) # comp
        self.assertEqual(header[3], 0) # comment flags set
        # self.assertEqual(header[5:9], b'') # time, how to check?
        self.assertEqual(header[8], 2) # xfl
        self.assertEqual(header[9], 3) # os
        self.assertEqual(len(header), 10)

    def test_allocate_index_bytes(self):
        self.Writer._allocate_index_bytes()
        self.Writer.close()
        file = open(self.paths[0], 'rb')
        data = file.read()
        print(data, data[1], len(data))
        file.close()
        max_idx_num = 80
        max_idx = 8
        max_offset = 8
        self.assertEqual(len(data), ((max_idx + max_offset) * max_idx_num) + 1)

        self.assertEqual(len(data), max_idx_num * (max_idx + max_offset) + 1)

    def test_write_data(self):
        test_string = b'AAAAAAAAbbbbbbbbCCCCCCCC'
        self.Writer._write_data(test_string)
        self.Writer.close()
        Decomp = zlib.decompressobj(-zlib.MAX_WBITS,)
        file = open(
            os.path.join(
                os.path.dirname(__file__),
                'data',
                'unittest.mzml'
            ),
            'rb'
        )
        data = file.read()
        file.close()
        compData = data[:-8]
        crc      = struct.unpack('<L', data[-8:-4])[0]
        isize    = struct.unpack('<L', data[-4:])[0]
        self.assertEqual(Decomp.decompress(compData), test_string)
        self.assertEqual(crc, zlib.crc32(test_string))
        self.assertEqual(isize, len(test_string) % 2**32)

    def test_add_data(self):
        test_string = b'AAAAAAAAbbbbbbbbCCCCCCCCdddddddd'
        self.Writer.add_data(test_string, 1)
        self.Writer.close()
        file = open(self.paths[0], 'rb')
        data = file.read()
        file.close()
        index = self.Writer.index
        self.assertIn(1, index)
        test_file = os.path.join(
            os.path.dirname(__file__),
            'data',
            'uncompressed',
            'CF_07062012_pH8_2_3A.mzML',
        )
        self.Writer = GSGW(test_file, max_idx= 80, max_idx_len=8, max_offset_len=8)
        self.Writer.add_data(test_string, 'a')
        self.Writer.close()
        file= open(self.paths[0], 'rb')
        data = file.read()
        file.close()
        index = self.Writer.index
        self.assertIn('a', index)

    def test_write_index(self):
        test_string = b'AAAAAAAAbbbbbbbbCCCCCCCCdddddddd'

        # with int as id
        # TODO assertions
        self.Writer.add_data(test_string, 1)
        self.Writer.write_index()
        self.Writer.close()
        file = open(self.paths[0], 'rb')
        data = file.read()
        file.close()
        index = data[15:15+(80*16)+1] # dont read header (first 15 bytes) and read idx_num * (idx_len + offset_len bytes) and zero termination
        identifier = index[:8].decode('latin-1')
        offset     = index[8:16].decode('latin-1')
        self.assertEqual(identifier.strip('\xAC'), '1')
        self.assertIsInstance(offset.strip('\xAC'), str)

if __name__ == '__main__':
    unittest.main(verbosity=3)
