<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of file_upload_model
 *
 * @author zmq163
 */
class File_upload_model extends CI_Model {
    private $mdb;
    public function __construct() {
        parent::__construct();
        $this->mdb = $this->load->database('mdb', TRUE);
    }

    /**
     * @param string $_chunk_encoded_base64_data This data is part of the big file in incoded base64.
     * 
     * @return boolean If chunk write success then return TRUE otherwise FALSE.
     * 
     */
    public function uploadFileInChunkIOTModel($file_upload_data) {
        if (($file_upload_data['chunk_id'] + 1) == $file_upload_data['total_chunk']) {
            $tempInsertUpdateStatus = $this->insertUpdateBase64Data($file_upload_data);
            $tempFileDataBase64Encode = $this->getRawMultimediaData($file_upload_data['file_name']);
            if ($tempInsertUpdateStatus and file_put_contents($this->returnFilePath($file_upload_data['file_type'], $file_upload_data['file_name']), $tempFileDataBase64Encode)) {
                $this->insertUpdateFileData(array('encode_base64_data' => base64_encode($tempFileDataBase64Encode), 'file_name' => $file_upload_data['file_name'], 'file_type' => $file_upload_data['file_type']));
                return array('submit_status' => TRUE, 'chunk_id' => $file_upload_data['chunk_id']);
            } else {
                return array('submit_status' => FALSE, 'chunk_id' => $file_upload_data['chunk_id']);
            }
        } else {
            return array('submit_status' => $this->insertUpdateBase64Data($file_upload_data), 'chunk_id' => $file_upload_data['chunk_id']);
        }
    }

    private function insertUpdateBase64Data($file_upload_data) {
        if ($file_upload_data['interrupt_chunk']) {
            if ($this->chunkCheckRow($file_upload_data['file_name'], $file_upload_data['chunk_id'])) {
                $this->mdb->set('encode_base64_data', $file_upload_data['chunk_data']);
                $this->mdb->where(array('chunk_id' => $file_upload_data['chunk_id'], 'file_name' => $file_upload_data['file_name']));
                $this->mdb->update('encoded_base64_data_temp');
                return ($this->getEncodeBase64String($this->mdb->insert_id(), $file_upload_data['chunk_size'])) ? TRUE : FALSE;
            } else {
                $this->mdb->insert('encoded_base64_data_temp', array('chunk_id' => $file_upload_data['chunk_id'], 'file_type' => $file_upload_data['file_type'], 'encode_base64_data' => $file_upload_data['chunk_data'], 'file_name' => $file_upload_data['file_name']));
                return ($this->getEncodeBase64String($this->mdb->insert_id(), $file_upload_data['chunk_size'])) ? TRUE : FALSE;
            }
        } else {
            if ($file_upload_data['update_chunk']) {
                $this->mdb->set('encode_base64_data', $file_upload_data['chunk_data']);
                $this->mdb->where(array('chunk_id' => $file_upload_data['chunk_id'], 'file_name' => $file_upload_data['file_name']));
                $this->mdb->update('encoded_base64_data_temp');
                return ($this->getEncodeBase64String($this->mdb->insert_id(), $file_upload_data['chunk_size'])) ? TRUE : FALSE;
            } else {
                $this->mdb->insert('encoded_base64_data_temp', array('chunk_id' => $file_upload_data['chunk_id'], 'file_type' => $file_upload_data['file_type'], 'encode_base64_data' => $file_upload_data['chunk_data'], 'file_name' => $file_upload_data['file_name']));
                return ($this->getEncodeBase64String($this->mdb->insert_id(), $file_upload_data['chunk_size'])) ? TRUE : FALSE;
            }
        }
    }

    private function getEncodeBase64String($encodeId, $fileSize) {
        $this->mdb->select('encoded_base64_data_temp.encode_base64_data');
        $this->mdb->from('encoded_base64_data_temp');
        $this->mdb->where('encoded_base64_data_temp.encode_id', $encodeId);
        $tempData = $this->getData($this->mdb->get());
        if ($tempData) {
            if (strlen($tempData[0]['encode_base64_data']) == $fileSize) {
                $this->mdb->set('status', 1);
                $this->mdb->where('encode_id', $encodeId);
                $this->mdb->update('encoded_base64_data_temp');
                return TRUE;
            } else {
                return FALSE;
            }
        } else {
            return FALSE;
        }
    }

    private function chunkCheckRow($file_name, $chunkId){
        $this->mdb->select('*');
        $this->mdb->from('encoded_base64_data_temp');
        $this->mdb->where(array('chunk_id' => $chunkId, 'file_name' => $file_name));
        return $this->getData($this->mdb->get());
    }

    private function insertUpdateFileData($fileDataInsert) {
        $tempFileName = $fileDataInsert['file_name'];
        $fileDataInsert['file_name'] = time() . '_' . $fileDataInsert['file_name'];
        $this->mdb->insert('encoded_base64_data', $fileDataInsert);
        if ($this->mdb->insert_id() ? TRUE : FALSE) {
            $this->mdb->where('file_name', $tempFileName);
            $this->mdb->delete('encoded_base64_data_temp');
        }
    }

    /**
     * 
     * @param type $_file_name
     * @return boolean|string
     * 
     * 
     */
    private function returnFilePath($_file_type = NULL, $_file_name = NULL) {
        $file_path = NULL;
        switch ($_file_type) {
            case 'audio':
                $file_path = './IOT/audio/' . $_file_name;
                break;
            case 'image':
                $file_path = './IOT/image/' . $_file_name;
                break;
            case 'text':
                $file_path = './IOT/text/' . $_file_name;
                break;
            case 'video':
                $file_path = './IOT/video/' . $_file_name;
                break;
        }
        return $file_path;
    }

    private function getRawMultimediaData($_file_name) {
        $this->mdb->select('*');
        $this->mdb->from('encoded_base64_data_temp');
        $this->mdb->where('file_name', $_file_name);
        $this->mdb->order_by('chunk_id', 'asc');
        $tempData = $this->getData($this->mdb->get());
        if ($tempData) {
            $tempEncodeBase64String = NULL;
            foreach ($tempData as $value) {
                $tempEncodeBase64String .= base64_decode(str_replace(' ', '+', $value['encode_base64_data']));
            }
            return $tempEncodeBase64String;
        } else {
            return FALSE;
        }
    }

    /**
     * 
     * 
     * 
     * 
     */
    private function getData($_query = NULL) {
        if ($_query != NULL and $_query->num_rows() > 0) {
            return $_query->result_array();
        } else {
            return FALSE;
        }
    }

}
