#
# 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
#
#     http://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.
#

from pystachio import Ref
from pystachio.matcher import Any, Matcher
from twitter.common.contextutil import temporary_file

from apache.aurora.client import binding_helper
from apache.aurora.client.binding_helper import BindingHelper, CachingBindingHelper
from apache.aurora.config import AuroraConfig


GENERIC_CONFIG = """
main_job = Job(
  name = 'hello_world',
  environment = 'prod',
  cluster = 'derp',
  task = Task(
    name = 'main',
    processes = [
      Process(name='hello_one', cmdline='{{uncached[hello]}} {{cached[hello]}}'),
      Process(name='hello_two', cmdline='{{uncached[hello]}} {{cached[hello]}}')
    ],
    resources = Resources(cpu = 0.1, ram = 64 * MB, disk = 64 * MB),
  )
)

jobs = [
  main_job(role = 'john_doe'),
  main_job(role = 'jane_doe'),
]
"""


class UncachedHelper(BindingHelper):
  @property
  def name(self):
    return 'uncached'

  @property
  def matcher(self):
    return Matcher('uncached')[Any]

  def __init__(self):
    self.binds = 0
    super(UncachedHelper, self).__init__()

  def bind(self, config, match, env, binding_dict):
    # TODO(wickman) You should be able to take a match tuple + matcher
    # object and return the ref.
    self.binds += 1
    ref = Ref.from_address('%s[%s]' % match)
    config.bind({ref: 'U(%s)' % match[1]})


class CachedHelper(CachingBindingHelper):
  @property
  def name(self):
    return 'cached'

  @property
  def matcher(self):
    return Matcher('cached')[Any]

  def __init__(self):
    self.binds, self.uncached_binds = 0, 0
    super(CachedHelper, self).__init__()

  def bind(self, *args, **kw):
    self.binds += 1
    super(CachedHelper, self).bind(*args, **kw)

  def uncached_bind(self, config, match, env, binding_dict):
    self.uncached_binds += 1
    ref = Ref.from_address('%s[%s]' % match)
    binding = {ref: 'C(%s)' % match[1]}
    config.bind(binding)
    return binding


def write_and_load_config(role):
  with temporary_file() as fp:
    fp.write(GENERIC_CONFIG)
    fp.flush()
    return AuroraConfig.load(fp.name, name='hello_world', select_role=role)


def test_registry():
  binding_helper.unregister_all()
  assert len(binding_helper._BINDING_HELPERS) == 0

  BindingHelper.register(UncachedHelper())
  assert len(binding_helper._BINDING_HELPERS) == 1

  BindingHelper.register(CachedHelper())
  assert len(binding_helper._BINDING_HELPERS) == 2

  binding_helper.unregister_all()
  assert len(binding_helper._BINDING_HELPERS) == 0


def test_helper_types():
  binding_helper.unregister_all()
  BindingHelper.register(UncachedHelper())
  BindingHelper.register(CachedHelper())

  uncached_helper = binding_helper._BINDING_HELPERS[0]
  cached_helper = binding_helper._BINDING_HELPERS[1]

  def smoke_test():
    cfg = write_and_load_config(role='john_doe')
    binding_helper.apply_all(cfg)
    assert cfg.task(0).processes()[0].cmdline().get() == 'U(hello) C(hello)'
    assert cfg.task(0).processes()[1].cmdline().get() == 'U(hello) C(hello)'

  # initially everything uncached (also -- multiple symbols result in a single bind)
  smoke_test()
  assert uncached_helper.binds == 1
  assert cached_helper.binds == 1
  assert cached_helper.uncached_binds == 1

  # cached helper is warm, should no longer have uncached binds
  smoke_test()
  assert uncached_helper.binds == 2
  assert cached_helper.binds == 2
  assert cached_helper.uncached_binds == 1

  # flush cache and validate miss
  binding_helper.clear_binding_caches()
  smoke_test()
  assert uncached_helper.binds == 3
  assert cached_helper.binds == 3
  assert cached_helper.uncached_binds == 2
