#!/usr/bin/env python
# -*- coding: cp936 -*-

import os
import binascii
import struct
import BaseProc
from ES.DataStruct import *
import logging
import logger
import dataSerial


logp = logger.FinalLogger.getLogger()



class ver1To2(BaseProc.BaseProc):
    def __init__(self):
        BaseProc.BaseProc.__init__(self, 1, 2)

    def process(self, inFn, inTID, inDst, inDstTopDir):
        logp.debug ('%d to %d with test id %d', self.old, self.new, inTID)
        fd = open(inFn, 'rb')
        data = fd.read()
        oldFileSize = os.path.getsize(inFn)
        fd.close()
        
        if (self.old == struct.unpack("<I",data[0:4])[0]):
            os.rename(inFn, inFn + '.pre' + str(self.old))
            fd = open(inFn, 'wb')
            newVer = struct.pack("<I", self.new)
            fd.write(newVer)

            #ver1 到 ver3 ah wh
            stream = BaseProc.stream2struct(data[4 : sizeof(ver1TMsgSaveEngine) + 4], ver1TMsgSaveEngine)

            #首次转换时,写入相关内容到文件
            if (inDst == self.old):
                dataSer = dataSerial.DataSerial.getDataSerial(inDstTopDir)
                dataSer.debug("%d-%d-%d-%d-%d", stream.channelNoInfoRow, stream.channelNoInfoCol, stream.channelNoInfoIndex, stream.testId, stream.dfDataIndex - 1)
                
            if inTID:#测试ID不为0时,更新
                stream.testId = inTID

            #1版本中的主通道类型是错误的;在这里修正之
            stream.chType = 0x04
            #取 CCCStepCnt 及之前的数据并写入 c_float * 100
            npose = sizeof(ver1TMsgSaveEngine) - 4
            newdata = BaseProc.struct2stream(stream)
            fd.write(newdata[0 : npose])
            crc32 = binascii.crc32(newdata[0 : npose])
            
            #填充ctrlStepStatus 数据
            fd.write(c_ubyte(0))
            #填充ctrlStepSetVal 数据
            fd.write(c_ubyte(0))
            crc32 = binascii.crc32(c_ubyte(0), crc32)
            crc32 = binascii.crc32(c_ubyte(0), crc32)

            ##写入 stepSwitchNum
            fd.write(newdata[npose : npose + 4])
            npose += 4
            crc32 = binascii.crc32(c_uint(stream.stepSwitchNum), crc32)
            
            #填充　ver2 其它数据为0
            numFill = (100 + 1 + 1 + 1) * 4
            for i in range(0,numFill):
                fd.write(c_ubyte(0))
                crc32 = binascii.crc32(c_ubyte(0), crc32)
            
            #ver1 到 ver2 该处未变化，直接写入该数据
            #data 中需要再加4
            npose += 4
            if (stream.cycleStackSize > 0):
                #8 -> 12 代码中未按字节对齐,因为占12字节
                fd.write(data[npose : npose + stream.cycleStackSize * 12])
                crc32 = binascii.crc32(data[npose : npose + stream.cycleStackSize * 12], crc32)
            npose += stream.cycleStackSize * 12
            
            #ver1 到 ver2 该处多了一个字节的类型,处理后写入该数据
            for j in range(0,stream.auxChNum) :
                #写入变化前的内容
                fd.write(data[npose : npose + 2])
                crc32 = binascii.crc32(data[npose : npose + 2], crc32)
                npose += 2
                #写入1个字节
                ibyte = b'\xFF'
                fd.write(ibyte)
                crc32 = binascii.crc32(ibyte, crc32)
                #写入其他数据
                fd.write(data[npose : npose + sizeof(ver123TAchInfoOfEngineState) - 3])
                crc32 = binascii.crc32(data[npose : npose + sizeof(ver123TAchInfoOfEngineState) - 3], crc32)
                npose += sizeof(ver123TAchInfoOfEngineState) - 3
            
            #ver1此处紧接的4字节和最后8字节之间的数据,ver2中也有，但保存的数据不一样，无法处理，但在ver3中又是不需要的，
            #因此，做为过渡，这些数据可以不写入。转换后的数据，不能在ver2的程序中加载运行。会有问题。
            #所以，只写入紧接的4字节和最后8字节之间的数据，按ver3中的处理，可以这样做
            fd.write(data[npose : npose + 4])
            crc32 = binascii.crc32(data[npose : npose + 4], crc32)

            npose = oldFileSize - 8
            fd.write(data[npose : npose + 8])
            crc32 = binascii.crc32(data[npose : npose + 8], crc32)

            #填充　ver2　中的 mESWriteSer
            fd.write(c_uint(3))
            crc32 = binascii.crc32(c_uint(3), crc32)
            fd.write(struct.pack("<I", crc32))
            fd.close()
            return 0
        else:
            logp.error ('old ver in file not equal to' + self.old )
            return 1





