# Useful reading is:
# https://zulip.readthedocs.io/en/latest/subsystems/html-css.html#front-end-build-process

import os
from typing import Optional

from django.conf import settings
from django.contrib.staticfiles.storage import ManifestStaticFilesStorage

if settings.DEBUG:
    from django.contrib.staticfiles.finders import find

    def static_path(path: str) -> str:
        return find(path) or "/nonexistent"

else:

    def static_path(path: str) -> str:
        return os.path.join(settings.STATIC_ROOT, path)


class IgnoreBundlesManifestStaticFilesStorage(ManifestStaticFilesStorage):
    def hashed_name(
        self, name: str, content: Optional[str] = None, filename: Optional[str] = None
    ) -> str:
        ext = os.path.splitext(name)[1]
        if name.startswith("webpack-bundles"):
            # Hack to avoid renaming already-hashnamed webpack bundles
            # when minifying; this was causing every bundle to have
            # two hashes appended to its name, one by webpack and one
            # here.  We can't just skip processing of these bundles,
            # since we do need the Django storage to add these to the
            # manifest for django_webpack_loader to work.  So, we just
            # use a no-op hash function for these already-hashed
            # assets.
            return name
        if ext in [".png", ".gif", ".jpg", ".svg"]:
            # Similarly, don't hash-rename image files; we only serve
            # the original file paths (not the hashed file paths), and
            # so the only effect of hash-renaming these is to increase
            # the size of release tarballs with duplicate copies of these.
            #
            # One could imagine a future world in which we instead
            # used the hashed paths for these; in that case, though,
            # we should instead be removing the non-hashed paths.
            return name
        if ext in ["json", "po", "mo", "mp3", "ogg", "html"]:
            # And same story for translation files, sound files, etc.
            return name
        return super().hashed_name(name, content, filename)


class ZulipStorage(IgnoreBundlesManifestStaticFilesStorage):
    # This is a hack to use staticfiles.json from within the
    # deployment, rather than a directory under STATIC_ROOT.  By doing
    # so, we can use a different copy of staticfiles.json for each
    # deployment, which ensures that we always use the correct static
    # assets for each deployment.
    manifest_name = os.path.join(settings.DEPLOY_ROOT, "staticfiles.json")

    def path(self, name: str) -> str:
        if name == self.manifest_name:
            return name
        return super().path(name)
