#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

import bb
import json
import subprocess

_ALWAYS_SAFE = frozenset('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                         'abcdefghijklmnopqrstuvwxyz'
                         '0123456789'
                         '_.-~')

MISSING_OK = object()

REGISTRY = "https://registry.npmjs.org"

# we can not use urllib.parse here because npm expects lowercase
# hex-chars but urllib generates uppercase ones
def uri_quote(s, safe = '/'):
    res = ""
    safe_set = set(safe)
    for c in s:
        if c in _ALWAYS_SAFE or c in safe_set:
            res += c
        else:
            res += '%%%02x' % ord(c)
    return res

class PackageJson:
    def __init__(self, spec):
        self.__spec = spec

    @property
    def name(self):
        return self.__spec['name']

    @property
    def version(self):
        return self.__spec['version']

    @property
    def empty_manifest(self):
        return {
            'name': self.name,
            'description': self.__spec.get('description', ''),
            'versions': {},
        }

    def base_filename(self):
        return uri_quote(self.name, safe = '@')

    def as_manifest_entry(self, tarball_uri):
        res = {}

        ## NOTE: 'npm install' requires more than basic meta information;
        ## e.g. it takes 'bin' from this manifest entry but not the actual
        ## 'package.json'
        for (idx,dflt) in [('name', None),
                           ('description', ""),
                           ('version', None),
                           ('bin', MISSING_OK),
                           ('man', MISSING_OK),
                           ('scripts', MISSING_OK),
                           ('directories', MISSING_OK),
                           ('dependencies', MISSING_OK),
                           ('devDependencies', MISSING_OK),
                           ('optionalDependencies', MISSING_OK),
                           ('license', "unknown")]:
            if idx in self.__spec:
                res[idx] = self.__spec[idx]
            elif dflt == MISSING_OK:
                pass
            elif dflt != None:
                res[idx] = dflt
            else:
                raise Exception("%s-%s: missing key %s" % (self.name,
                                                           self.version,
                                                           idx))

        res['dist'] = {
            'tarball': tarball_uri,
        }

        return res

class ManifestImpl:
    def __init__(self, base_fname, spec):
        self.__base = base_fname
        self.__spec = spec

    def load(self):
        try:
            with open(self.filename, "r") as f:
                res = json.load(f)
        except IOError:
            res = self.__spec.empty_manifest

        return res

    def save(self, meta):
        with open(self.filename, "w") as f:
            json.dump(meta, f, indent = 2)

    @property
    def filename(self):
        return self.__base + ".meta"

class Manifest:
    def __init__(self, base_fname, spec):
        self.__base = base_fname
        self.__spec = spec
        self.__lockf = None
        self.__impl = None

    def __enter__(self):
        self.__lockf = bb.utils.lockfile(self.__base + ".lock")
        self.__impl  = ManifestImpl(self.__base, self.__spec)
        return self.__impl

    def __exit__(self, exc_type, exc_val, exc_tb):
        bb.utils.unlockfile(self.__lockf)

class NpmCache:
    def __init__(self, cache):
        self.__cache = cache

    @property
    def path(self):
        return self.__cache

    def run(self, type, key, fname):
        subprocess.run(['oe-npm-cache', self.__cache, type, key, fname],
                       check = True)

class NpmRegistry:
    def __init__(self, path, cache):
        self.__path = path
        self.__cache = NpmCache(cache + '/_cacache')
        bb.utils.mkdirhier(self.__path)
        bb.utils.mkdirhier(self.__cache.path)

    @staticmethod
    ## This function is critical and must match nodejs expectations
    def _meta_uri(spec):
        return REGISTRY + '/' + uri_quote(spec.name, safe = '@')

    @staticmethod
    ## Exact return value does not matter; just make it look like a
    ## usual registry url
    def _tarball_uri(spec):
        return '%s/%s/-/%s-%s.tgz' % (REGISTRY,
                                      uri_quote(spec.name, safe = '@'),
                                      uri_quote(spec.name, safe = '@/'),
                                      spec.version)

    def add_pkg(self, tarball, pkg_json):
        pkg_json = PackageJson(pkg_json)
        base = os.path.join(self.__path, pkg_json.base_filename())

        with Manifest(base, pkg_json) as manifest:
            meta = manifest.load()
            tarball_uri = self._tarball_uri(pkg_json)

            meta['versions'][pkg_json.version] = pkg_json.as_manifest_entry(tarball_uri)

            manifest.save(meta)

            ## Cache entries are a little bit dependent on the nodejs
            ## version; version specific cache implementation must
            ## mitigate differences
            self.__cache.run('meta', self._meta_uri(pkg_json), manifest.filename);
            self.__cache.run('tgz',  tarball_uri, tarball);
