# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from contextlib import contextmanager

from recipe_engine import recipe_api


class GomaApi(recipe_api.RecipeApi):
    """GomaApi contains helper functions for using goma."""

    def __init__(self, **kwargs):
        super(GomaApi, self).__init__(**kwargs)
        self._goma_dir = None
        self._goma_started = False

        self._goma_ctl_env = {}
        self._goma_jobs = None

    @property
    def service_account_json_path(self):
        return '/creds/service_accounts/service-account-goma-client.json'

    @property
    def json_path(self):
        assert self._goma_dir
        return self.m.path.join(self._goma_dir, 'jsonstatus')

    @property
    def recommended_goma_jobs(self):
        """
        Return the recommended number of jobs for parallel build using Goma.

        This function caches the _goma_jobs.
        """
        if self._goma_jobs:
            return self._goma_jobs

        # We need to use python.inline not to change behavior of recipes.
        step_result = self.m.python.inline(
            'calculate the number of recommended jobs',
            """
import multiprocessing
import sys

job_limit = 200
if sys.platform.startswith('linux'):
  # Use 80 for linux not to load goma backend.
  job_limit = 80

try:
  jobs = min(job_limit, multiprocessing.cpu_count() * 10)
except NotImplementedError:
  jobs = 50

print jobs
            """,
            stdout=self.m.raw_io.output(),
            step_test_data=(
                lambda: self.m.raw_io.test_api.stream_output('50\n'))
        )
        self._goma_jobs = int(step_result.stdout)

        return self._goma_jobs

    def ensure_goma(self, canary=False):
        with self.m.step.nest('ensure_goma'):
            with self.m.step.context({'infra_step': True}):
                self.m.cipd.set_service_account_credentials(
                    self.service_account_json_path)

                goma_package = ('infra_internal/goma/client/%s' %
                    self.m.cipd.platform_suffix())
                ref='release'
                if canary:
                    ref='candidate'
                self._goma_dir = self.m.path['start_dir'].join('cipd', 'goma')

                self.m.cipd.ensure(self._goma_dir, {goma_package: ref})

                return self._goma_dir

    @property
    def goma_ctl(self):
        return self.m.path.join(self._goma_dir, 'goma_ctl.py')

    @property
    def goma_dir(self):
        assert self._goma_dir
        return self._goma_dir

    def start(self, env=None, **kwargs):
        """Start goma compiler_proxy.

        A user MUST execute ensure_goma beforehand.
        It is user's responsibility to handle failure of starting compiler_proxy.
        """
        assert self._goma_dir
        assert not self._goma_started

        self._goma_ctl_env['GOMA_CACHE_DIR'] = (
            self.m.path.join(self.m.path['cache'], 'goma'))
        self._goma_ctl_env['GOMA_SERVICE_ACCOUNT_JSON_FILE'] = (
            self.service_account_json_path)

        # GLOG_log_dir should not be set.
        assert env is None or 'GLOG_log_dir' not in env

        goma_ctl_start_env = self._goma_ctl_env.copy()
        if env is not None:
            goma_ctl_start_env.update(env)

        try:
            self.m.python(
                name='start_goma',
                script=self.goma_ctl,
                args=['restart'], env=goma_ctl_start_env, infra_step=True, **kwargs)
            self._goma_started = True
        except self.m.step.InfraFailure as e: # pragma: no cover
            try:
                with self.m.step.defer_results():
                    self.m.python(
                        name='stop_goma (start failure)',
                        script=self.goma_ctl,
                        args=['stop'], env=self._goma_ctl_env, **kwargs)
            except self.m.step.StepFailure:
                pass
            raise e

    def stop(self, **kwargs):
        """Stop goma compiler_proxy.

        A user MUST execute start beforehand.
        It is user's responsibility to handle failure of stopping compiler_proxy.

        Raises:
            StepFailure if it fails to stop goma.
        """
        assert self._goma_dir
        assert self._goma_started

        with self.m.step.defer_results():
            self.m.python(name='goma_jsonstatus', script=self.goma_ctl,
                          args=['jsonstatus', self.json_path],
                          env=self._goma_ctl_env, **kwargs)
            self.m.python(name='goma_stat', script=self.goma_ctl,
                          args=['stat'],
                          env=self._goma_ctl_env, **kwargs)
            self.m.python(name='stop_goma', script=self.goma_ctl,
                          args=['stop'], env=self._goma_ctl_env, **kwargs)

        self._goma_started = False
        self._goma_ctl_env = {}

    @contextmanager
    def build_with_goma(self, env=None):
        """Make context wrapping goma start/stop.

        Raises:
            StepFailure or InfraFailure if it fails to build.
        """

        self.start(env)
        try:
            yield
        finally:
            self.stop()
