# Copyright 2022 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Install and check status of PicoTool."""

from contextlib import contextmanager
import logging
import os
import pathlib
from pathlib import Path
import shlex
import shutil
import subprocess
from typing import Sequence

import pw_package.git_repo
import pw_package.package_manager

_LOG = logging.getLogger(__package__)


@contextmanager
def change_working_dir(directory: Path):
    original_dir = Path.cwd()
    try:
        os.chdir(directory)
        yield directory
    finally:
        os.chdir(original_dir)


class PicoTool(pw_package.package_manager.Package):
    """Install and check status of PicoTool."""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, name='picotool', **kwargs)

        self._pico_tool_repo = pw_package.git_repo.GitRepo(
            name='picotool',
            url='https://github.com/raspberrypi/picotool.git',
            commit='03f28122cc170535f35e5bf8fa37be024489f5eb',
        )

    def install(self, path: Path) -> None:
        self._pico_tool_repo.install(path)

        env = os.environ.copy()
        env['PICO_SDK_PATH'] = str(path.parent.absolute() / 'pico_sdk')
        bootstrap_env_path = Path(env.get('_PW_ACTUAL_ENVIRONMENT_ROOT', ''))

        commands = [
            'cmake -S ./ -B out/ -G Ninja',
            'ninja -C out',
        ]

        with change_working_dir(path) as _picotool_repo:
            for command in commands:
                _LOG.info('==> %s', command)
                subprocess.run(shlex.split(command),
                               env=env,
                               capture_output=True,
                               check=True)

        picotool_bin = path / 'out/picotool'
        _LOG.info('Done! picotool binary located at:')
        _LOG.info(picotool_bin)

        if bootstrap_env_path.is_dir() and picotool_bin.is_file():
            bin_path = bootstrap_env_path / 'cipd/packages/pigweed/bin'
            destination_path = bin_path / picotool_bin.name
            _LOG.info('Copy %s -> %s', picotool_bin, destination_path)
            shutil.copyfile(picotool_bin, destination_path)

    def info(self, path: pathlib.Path) -> Sequence[str]:
        return (
            f'{self.name} installed in: {path}',
            "Enable by running 'gn args out' and adding this line:",
            f'  PICO_TOOL_DIR = "{path}"',
        )


pw_package.package_manager.register(PicoTool)
