# -*- coding: utf-8 -*-

import os

import shortuuid
from django.conf import settings
from django.core.files.storage import default_storage
from django.db import transaction
from filemd5 import calculate_md5

from photo.models import PhotoUUIDInfo
from utils.qiniucdn import upload_file_path
from utils.thumbnail_utils import make_thumbnail
from utils.watermark_utils import watermark_wrap


class DotDict(dict):
    """ dot.notation access to dictionary attributes """
    def __getattr__(self, attr):
        return self.get(attr)
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__


def file_abspath(file_path=None):
    return os.path.join(settings.MEDIA_ROOT, file_path).replace('\\', '/')


@transaction.atomic
def file_save(file_=None, file_path=None, prefix='img', ext='.jpeg', watermark=False, thumbnail=False):
    photo_path, photo_watermark_path, photo_thumbnail_path, photo_thumbnail2_path = '', '', '', ''

    # Photo
    file_ = file_ or default_storage.open(file_path)

    # Ext
    ext = os.path.splitext(file_.name)[-1] or ext

    # Photo MD5
    photo_md5 = calculate_md5(file_)

    # Photo UUID Get or Create
    photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=photo_md5)

    # 无水印
    if not photo.photo_path:
        photo_path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext)
        if default_storage.exists(photo_path):
            default_storage.delete(photo_path)
        default_storage.save(photo_path, file_)
        photo_path_qiniu = upload_file_path(file_abspath(photo_path), bucket='photo')
        photo.photo_path = photo_path_qiniu
        photo.save()
    else:
        if ((watermark and not photo.photo_watermark_path) or (thumbnail and not (photo.photo_thumbnail_path and photo.photo_thumbnail2_path))) and (not default_storage.exists(photo.photo_path)):
            default_storage.save(photo.photo_path, file_)

    # 有水印
    if watermark:
        if not photo.photo_watermark_path:
            if settings.WATERMARK_OR_NOT:
                photo_watermark_path = 'photo/{}{}'.format(shortuuid.uuid(), ext)
                watermark_wrap(
                    file_abspath(photo_path),
                    settings.WATERMARK_LOGO_PATH,
                    file_abspath(photo_watermark_path)
                )
                photo_watermark_path_qiniu = upload_file_path(file_abspath(photo_watermark_path), bucket='watermark')
                photo.photo_watermark_path = photo_watermark_path_qiniu
            else:
                photo.photo_watermark_path = photo_path_qiniu
            photo.save()

    # 缩略图
    if thumbnail:
        if not photo.photo_thumbnail_path:
            # 双列: 540, 40-50K
            photo_thumbnail_path = photo_path.replace('.', '_thumbnail.')
            photo_w, photo_h, photo_thumbnail_w, photo_thumbnail_h = make_thumbnail(
                file_abspath(photo_path),
                file_abspath(photo_thumbnail_path),
                settings.THUMBNAIL_MAX_WIDTH
            )
            photo_thumbnail_path_qiniu = upload_file_path(file_abspath(photo_thumbnail_path), bucket='thumbnail')
            photo.photo_w = photo_w
            photo.photo_h = photo_h
            photo.photo_thumbnail_path = photo_thumbnail_path_qiniu
            photo.photo_thumbnail_w = photo_thumbnail_w
            photo.photo_thumbnail_h = photo_thumbnail_h
        if not photo.photo_thumbnail2_path:
            # 单列: 1080, xx-100K
            photo_thumbnail2_path = photo_path.replace('.', '_thumbnail2.')
            photo_w, photo_h, photo_thumbnail2_w, photo_thumbnail2_h = make_thumbnail(
                file_abspath(photo_path),
                file_abspath(photo_thumbnail2_path),
                settings.THUMBNAIL_MAX_WIDTH2
            )
            if watermark and settings.WATERMARK_OR_NOT:
                watermark_wrap(
                    file_abspath(photo_thumbnail2_path),
                    settings.WATERMARK_LOGO_PATH,
                    file_abspath(photo_thumbnail2_path)
                )
            photo_thumbnail2_path_qiniu = upload_file_path(file_abspath(photo_thumbnail2_path), bucket='thumbnail2')
            photo.photo_w = photo_w
            photo.photo_h = photo_h
            photo.photo_thumbnail2_path = photo_thumbnail2_path_qiniu
            photo.photo_thumbnail2_w = photo_thumbnail2_w
            photo.photo_thumbnail2_h = photo_thumbnail2_h
        photo.save()

    # 本地删除
    for path in [photo_path, photo_watermark_path, photo_thumbnail_path, photo_thumbnail2_path]:
        if path and default_storage.exists(path):
            default_storage.delete(path)

    return DotDict({
        'ext': ext,

        'photo_md5': photo_md5,

        'photo_path': photo.photo_path,
        'photo_w': photo.photo_w,
        'photo_h': photo.photo_h,

        'photo_watermark_path': photo.photo_watermark_path,

        'photo_thumbnail_path': photo.photo_thumbnail_path,
        'photo_thumbnail_w': photo.photo_thumbnail_w,
        'photo_thumbnail_h': photo.photo_thumbnail_h,

        'photo_thumbnail2_path': photo.photo_thumbnail2_path,
        'photo_thumbnail2_w': photo.photo_thumbnail2_w,
        'photo_thumbnail2_h': photo.photo_thumbnail2_h,
    })