# -*- coding: utf-8 -*-
import os
import os.path
import hashlib
import time


class OpcacheChecker(object):
    OPCACHE = "_opcache"

    def __init__(self, logger, unzip_path, install_path):
        self._logger = logger
        self._unzip_path = "{0}/main".format(unzip_path)
        self._install_path = install_path

    def check(self):
        unzip_opcache_path = os.path.join(self._unzip_path, OpcacheChecker.OPCACHE)
        if not os.path.exists(unzip_opcache_path):
            return True

        # 如果有_opcache目录，先sleep一秒再检查
        time.sleep(1)

        install_opcache_path = os.path.join(self._install_path, OpcacheChecker.OPCACHE)
        for root, dirs, files in os.walk(unzip_opcache_path):
            relative_path = root.split(unzip_opcache_path)[1].strip("/")
            install_root = os.path.join(install_opcache_path, relative_path)
            for f in files:
                if not f.endswith(".php.bin"):
                    continue
                unzip_path_md5 = self._cal_md5(os.path.join(root, f))
                install_path_md5 = self._cal_md5(os.path.join(install_root, f))
                self._logger.debug("checking {0}, {1}, {2}".format(f, unzip_path_md5, install_path_md5))
                if unzip_path_md5 != install_path_md5:
                    self._logger.error("opcache check error, md5 not same, unzip path({0}, {1}), install path({2}, {3})".format(
                        os.path.join(root, f),
                        unzip_path_md5,
                        os.path.join(install_root, f),
                        install_path_md5
                    ))
                    return False
        return True

    def _cal_md5(self, fname):
        if not os.path.exists(fname):
            return None
        hash_md5 = hashlib.md5()
        with open(fname, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()
