#!/usr/bin/env python
# Copyright (c) 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.

import signal
import socket
import sys

from infra_libs import app
from infra_libs import experiments
from infra.services.service_manager import cloudtail_factory
from infra.services.service_manager import config_watcher


class ServiceManager(app.BaseApplication):
  DESCRIPTION = ('Starts and stops machine-wide infra services with arguments '
                 'from config files')

  def add_argparse_options(self, parser):
    super(ServiceManager, self).add_argparse_options(parser)

    if sys.platform == 'win32':
      default_state_directory = 'C:\\chrome-infra\\service-state'
      default_config_directory = 'C:\\chrome-infra\\service-config'
      default_cipd_version_file = 'C:\\infra-python\\CIPD_VERSION.json'
      default_cloudtail_path = 'C:\\infra-python\\go\\bin\\cloudtail.exe'
    else:
      default_state_directory = '/var/run/infra-services'
      default_config_directory = '/etc/infra-services'
      default_cipd_version_file = '/opt/infra-python/CIPD_VERSION.json'
      default_cloudtail_path = '/opt/infra-python/go/bin/cloudtail'

    parser.add_argument(
        '--state-directory',
        default=default_state_directory,
        help='directory to store PID files (default %(default)s)')
    parser.add_argument(
        '--config-directory',
        default=default_config_directory,
        help='directory to read JSON config files (default %(default)s)')
    parser.add_argument(
        '--root-directory',
        help='deprecated and ignored')
    parser.add_argument(
        '--cipd-version-file',
        default=default_cipd_version_file,
        help='path to the version file for service_manager\'s own CIPD package.'
             ' If this package is updated the process will exit')

    parser.add_argument(
        '--config-poll-interval',
        default=10,
        help='how frequently (in seconds) to poll the config directory')
    parser.add_argument(
        '--service-poll-interval',
        default=10,
        help='how frequently (in seconds) to restart failed services')

    parser.add_argument(
        '--cloudtail-path',
        default=default_cloudtail_path,
        help='path to the cloudtail binary (default %(default)s)')
    parser.add_argument(
        '--cloudtail-ts-mon-credentials',
        help='path to a pkcs8 json credential file to pass on to the cloudtail '
             'binary')

    parser.set_defaults(
        ts_mon_target_type='task',
        ts_mon_task_service_name='service_manager',
        ts_mon_task_job_name='service_manager',
    )

  def main(self, opts):
    if opts.cloudtail_path:
      cloudtail = cloudtail_factory.CloudtailFactory(
          opts.cloudtail_path,
          opts.cloudtail_ts_mon_credentials)
    else:
      cloudtail = cloudtail_factory.DummyCloudtailFactory()

    watcher = config_watcher.ConfigWatcher(
        opts.config_directory,
        opts.config_poll_interval,
        opts.service_poll_interval,
        opts.state_directory,
        opts.cipd_version_file,
        cloudtail)

    def sigint_handler(_signal, _frame):
      watcher.stop()

    previous_sigint_handler = signal.signal(signal.SIGINT, sigint_handler)
    watcher.run()
    signal.signal(signal.SIGINT, previous_sigint_handler)


if __name__ == '__main__':
  ServiceManager().run()

