#!/usr/bin/env python2.7
# Copyright 2020 The Fuchsia 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 errno

from args import ArgParser
from host import Host
from buildenv import BuildEnv
from device import Device
from fuzzer import Fuzzer


class Factory(object):
    """Facility for creating associated objects.

    The factory can create Hosts, BuildEnvs, Devices, and
    Fuzzers. More importantly, it can construct them with references to
    each other, i.e. a Factory-constructed Fuzzer automatically gets a
    reference to a Factory-constructed Device, which has a reference to a
    Factory-constructed BuildEnv.

    Attributes:
        host:           System interface object for user interactions.
        buildenv:       The associated BuildEnv object.
        device:         The associated Device object.
    """

    def __init__(self, host=None):
        if not host:
            host = Host()
        self._parser = None
        self._host = host
        self._buildenv = None
        self._device = None

    @property
    def host(self):
        """System interface object for user interactions."""
        return self._host

    @property
    def parser(self):
        """The associated ArgParser object."""
        if self._parser:
            return self._parser
        parser = ArgParser()
        parser.host = self.host
        parser.add_parsers()
        self._parser = parser
        return self._parser

    @property
    def buildenv(self):
        """The associated BuildEnv object."""
        if self._buildenv:
            return self._buildenv
        buildenv = BuildEnv(self)
        pathname = buildenv.abspath('//.fx-build-dir')
        build_dir = '//' + self.host.readfile(
            pathname,
            on_error=[
                'Failed to read build directory from {}.'.format(pathname),
                'Have you run "fx set ... --fuzz-with <sanitizer>"?'
            ])
        buildenv.configure(build_dir)
        buildenv.read_fuzzers(buildenv.abspath(build_dir, 'fuzzers.json'))
        self._buildenv = buildenv
        return self._buildenv

    @property
    def device(self):
        """The associated Device object."""
        if self._device:
            return self._device
        pathname = '{}.device'.format(self.buildenv.build_dir)
        device_name = self.host.readfile(pathname, missing_ok=True)
        device = Device(self, name=device_name)
        device.configure()
        self._device = device
        return self._device

    def create_fuzzer(self, args, include_tests=False):
        """Constructs a Fuzzer from command line arguments, showing a
        disambiguation menu if specified name matches more than one fuzzer."""
        fuzzers = self.buildenv.fuzzers(args.name, include_tests=include_tests)
        if not fuzzers:
            self.host.error('No matching fuzzers found.', 'Try "fx fuzz list".')
        if len(fuzzers) > 1:
            choices = {}
            for fuzzer in fuzzers:
                choices[str(fuzzer)] = fuzzer
            self.host.echo('More than one match found.')
            prompt = 'Please pick one from the list'
            choice = self.host.choose(prompt, sorted(choices.keys()))
            fuzzer = choices[choice]
        else:
            fuzzer = fuzzers[0]
        fuzzer.update(args)
        return fuzzer