import os
import shutil
import logging
import hashlib

from django.apps import AppConfig
from django.conf import settings


logger = logging.getLogger("inventree")


def hashFile(filename):
    """
    Calculate the MD5 hash of a file
    """

    md5 = hashlib.md5()

    with open(filename, 'rb') as f:
        data = f.read()
        md5.update(data)

    return md5.hexdigest()


class LabelConfig(AppConfig):
    name = 'label'

    def ready(self):
        """
        This function is called whenever the label app is loaded
        """

        self.create_stock_item_labels()
        self.create_stock_location_labels()

    def create_stock_item_labels(self):
        """
        Create database entries for the default StockItemLabel templates,
        if they do not already exist
        """

        try:
            from .models import StockItemLabel
        except:
            # Database might not by ready yet
            return

        src_dir = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            'templates',
            'label',
            'stockitem',
        )

        dst_dir = os.path.join(
            settings.MEDIA_ROOT,
            'label',
            'inventree',
            'stockitem',
        )

        if not os.path.exists(dst_dir):
            logger.info(f"Creating missing directory: '{dst_dir}'")
            os.makedirs(dst_dir, exist_ok=True)

        labels = [
            {
                'file': 'qr.html',
                'name': 'QR Code',
                'description': 'Simple QR code label',
                'width': 24,
                'height': 24,
            },
        ]

        for label in labels:

            filename = os.path.join(
                'label',
                'inventree',
                'stockitem',
                label['file'],
            )

            # Check if the file exists in the media directory
            src_file = os.path.join(src_dir, label['file'])
            dst_file = os.path.join(settings.MEDIA_ROOT, filename)

            to_copy = False

            if os.path.exists(dst_file):
                # File already exists - let's see if it is the "same",
                # or if we need to overwrite it with a newer copy!

                if not hashFile(dst_file) == hashFile(src_file):
                    logger.info(f"Hash differs for '{filename}'")
                    to_copy = True

            else:
                logger.info(f"Label template '{filename}' is not present")
                to_copy = True

            if to_copy:
                logger.info(f"Copying label template '{dst_file}'")
                shutil.copyfile(src_file, dst_file)

            try:
                # Check if a label matching the template already exists
                if StockItemLabel.objects.filter(label=filename).exists():
                    continue

                logger.info(f"Creating entry for StockItemLabel '{label['name']}'")

                StockItemLabel.objects.create(
                    name=label['name'],
                    description=label['description'],
                    label=filename,
                    filters='',
                    enabled=True,
                    width=label['width'],
                    height=label['height'],
                )
            except:
                pass

    def create_stock_location_labels(self):
        """
        Create database entries for the default StockItemLocation templates,
        if they do not already exist
        """

        try:
            from .models import StockLocationLabel
        except:
            # Database might not yet be ready
            return
        
        src_dir = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            'templates',
            'label',
            'stocklocation',
        )

        dst_dir = os.path.join(
            settings.MEDIA_ROOT,
            'label',
            'inventree',
            'stocklocation',
        )

        if not os.path.exists(dst_dir):
            logger.info(f"Creating missing directory: '{dst_dir}'")
            os.makedirs(dst_dir, exist_ok=True)

        labels = [
            {
                'file': 'qr.html',
                'name': 'QR Code',
                'description': 'Simple QR code label',
                'width': 24,
                'height': 24,
            },
            {
                'file': 'qr_and_text.html',
                'name': 'QR and text',
                'description': 'Label with QR code and name of location',
                'width': 50,
                'height': 24,
            }
        ]

        for label in labels:

            filename = os.path.join(
                'label',
                'inventree',
                'stocklocation',
                label['file'],
            )

            # Check if the file exists in the media directory
            src_file = os.path.join(src_dir, label['file'])
            dst_file = os.path.join(settings.MEDIA_ROOT, filename)

            to_copy = False

            if os.path.exists(dst_file):
                # File already exists - let's see if it is the "same",
                # or if we need to overwrite it with a newer copy!

                if not hashFile(dst_file) == hashFile(src_file):
                    logger.info(f"Hash differs for '{filename}'")
                    to_copy = True

            else:
                logger.info(f"Label template '{filename}' is not present")
                to_copy = True

            if to_copy:
                logger.info(f"Copying label template '{dst_file}'")
                shutil.copyfile(src_file, dst_file)

            try:
                # Check if a label matching the template already exists
                if StockLocationLabel.objects.filter(label=filename).exists():
                    continue

                logger.info(f"Creating entry for StockLocationLabel '{label['name']}'")

                StockLocationLabel.objects.create(
                    name=label['name'],
                    description=label['description'],
                    label=filename,
                    filters='',
                    enabled=True,
                    width=label['width'],
                    height=label['height'],
                )
            except:
                pass
