#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Update our node_modules bundle."""

from __future__ import print_function

import hashlib
import logging
import os
import sys

import libdot


def sha256(path):
    """Return sha256 hex digest of |path|."""
    # The file shouldn't be too big to load into memory, so be lazy.
    with open(path, 'rb') as fp:
        data = fp.read()
    m = hashlib.sha256()
    m.update(data)
    return m.hexdigest()


def get_parser():
    """Get a command line parser."""
    parser = libdot.ArgumentParser(description=__doc__)
    return parser


def main(argv):
    """The main func!"""
    parser = get_parser()
    _opts = parser.parse_args(argv)
    libdot.node_and_npm_setup()

    tar = 'node_modules.tar'
    os.chdir(libdot.LIBAPPS_DIR)

    libdot.unlink('package-lock.json')

    logging.info('Removing modules not listed in package.json')
    libdot.node.run(['npm', 'prune'])

    logging.info('Updating modules from package.json')
    libdot.node.run(['npm', 'upgrade', '--no-save'])

    logging.info('Creating tarball')
    libdot.run([
        'tar', '-cf', tar,
        '--exclude=node_modules/.hash',
        '--exclude=node_modules/.node/*',
        '--exclude=node_modules/.bin/node',
        '--exclude=node_modules/.bin/npm',
        '--exclude=node_modules/puppeteer/.local-chromium',
        'node_modules',
    ])

    logging.info('Compressing tarball')
    libdot.run(['xz', '-f', '-T0', '-9', tar])

    tar_xz = '%s.xz' % (tar,)
    new_hash = sha256(tar_xz)
    final_tar = 'node_modules-%s.tar.xz' % (new_hash,)
    os.rename(tar_xz, final_tar)

    logging.info(
        'To update the hash, run:\n'
        "sed -i \"/^NODE_MODULES_HASH *=/s:=.*:= '%s':\" '%s/node'",
        new_hash, libdot.BIN_DIR)
    logging.info('To upload the new modules:\ngsutil cp -a public-read %s %s/',
                 final_tar, libdot.node.NODE_MODULES_GS_URI)


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
