"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from .httpclient import AsyncHttpClient, ClientOwner, HttpClient, close_clients
from .sdkconfiguration import SDKConfiguration
from .utils.logger import Logger, get_default_logger
from .utils.retries import RetryConfig
from gusto_embedded import models, utils
from gusto_embedded._hooks import SDKHooks
from gusto_embedded.ach_transactions import ACHTransactions
from gusto_embedded.bank_accounts import BankAccounts
from gusto_embedded.companies import Companies
from gusto_embedded.company_attachment_sdk import CompanyAttachmentSDK
from gusto_embedded.company_benefits import CompanyBenefits
from gusto_embedded.companyfederaltaxes import CompanyFederalTaxes
from gusto_embedded.companyforms import CompanyForms
from gusto_embedded.compensations import Compensations
from gusto_embedded.contractor_documents import ContractorDocuments
from gusto_embedded.contractor_forms import ContractorForms
from gusto_embedded.contractor_payment_groups import ContractorPaymentGroups
from gusto_embedded.contractor_payment_method_sdk import ContractorPaymentMethodSDK
from gusto_embedded.contractor_payments import ContractorPayments
from gusto_embedded.contractorpaymentmethods import ContractorPaymentMethods
from gusto_embedded.contractors import Contractors
from gusto_embedded.departments import Departments
from gusto_embedded.earning_types import EarningTypes
from gusto_embedded.employee_addresses import EmployeeAddresses
from gusto_embedded.employee_benefits import EmployeeBenefits
from gusto_embedded.employee_employments import EmployeeEmployments
from gusto_embedded.employee_forms import EmployeeForms
from gusto_embedded.employee_payment_method_sdk import EmployeePaymentMethodSDK
from gusto_embedded.employee_tax_setup import EmployeeTaxSetup
from gusto_embedded.employeebankaccounts import EmployeeBankAccounts
from gusto_embedded.employeeonboarding import EmployeeOnboarding
from gusto_embedded.employeepaymentmethods import EmployeePaymentMethods
from gusto_embedded.employees import Employees
from gusto_embedded.employeetaxes import EmployeeTaxes
from gusto_embedded.employeeterminations import EmployeeTerminations
from gusto_embedded.events import Events
from gusto_embedded.external_payrolls import ExternalPayrolls
from gusto_embedded.federal_tax_details_sdk import FederalTaxDetailsSDK
from gusto_embedded.flows import Flows
from gusto_embedded.garnishments import Garnishments
from gusto_embedded.generated_documents import GeneratedDocuments
from gusto_embedded.holiday_pay_policies import HolidayPayPolicies
from gusto_embedded.homeaddresses import HomeAddresses
from gusto_embedded.i9authorizations import I9Authorizations
from gusto_embedded.i_9_verification import I9Verification
from gusto_embedded.industryselections import IndustrySelections
from gusto_embedded.introspection import Introspection
from gusto_embedded.invoices import Invoices
from gusto_embedded.jobcompensations import JobCompensations
from gusto_embedded.jobs import Jobs
from gusto_embedded.jobs_and_compensations import JobsAndCompensations
from gusto_embedded.locations import Locations
from gusto_embedded.notifications import Notifications
from gusto_embedded.pay_schedules import PaySchedules
from gusto_embedded.payment_configs_sdk import PaymentConfigsSDK
from gusto_embedded.payrolls import Payrolls
from gusto_embedded.payrollsdocuments import PayrollsDocuments
from gusto_embedded.paystubs import PayStubs
from gusto_embedded.recovery_cases import RecoveryCases
from gusto_embedded.reports import Reports
from gusto_embedded.reporttemplates import ReportTemplates
from gusto_embedded.signatories import Signatories
from gusto_embedded.tax_requirements import TaxRequirements
from gusto_embedded.terminations import Terminations
from gusto_embedded.time_off_policies import TimeOffPolicies
from gusto_embedded.types import OptionalNullable, UNSET
from gusto_embedded.webhooks import Webhooks
from gusto_embedded.webhooksubscriptions import WebhookSubscriptions
from gusto_embedded.wire_in_requests import WireInRequests
from gusto_embedded.workaddresses import WorkAddresses
import httpx
from typing import Any, Callable, Dict, Optional, Union, cast
import weakref


class Gusto(BaseSDK):
    r"""Gusto API: Welcome to Gusto's Embedded Payroll API documentation!"""

    introspection: Introspection
    companies: Companies
    invoices: Invoices
    company_attachment: CompanyAttachmentSDK
    company_federal_taxes: CompanyFederalTaxes
    federal_tax_details: FederalTaxDetailsSDK
    industry_selections: IndustrySelections
    signatories: Signatories
    flows: Flows
    locations: Locations
    bank_accounts: BankAccounts
    external_payrolls: ExternalPayrolls
    payment_configs: PaymentConfigsSDK
    pay_schedules: PaySchedules
    employees: Employees
    departments: Departments
    employee_terminations: EmployeeTerminations
    employee_employments: EmployeeEmployments
    terminations: Terminations
    employee_addresses: EmployeeAddresses
    home_addresses: HomeAddresses
    work_addresses: WorkAddresses
    employee_onboarding: EmployeeOnboarding
    employee_tax_setup: EmployeeTaxSetup
    employee_taxes: EmployeeTaxes
    employee_payment_methods: EmployeePaymentMethods
    employee_payment_method: EmployeePaymentMethodSDK
    employee_bank_accounts: EmployeeBankAccounts
    jobs_and_compensations: JobsAndCompensations
    jobs: Jobs
    job_compensations: JobCompensations
    compensations: Compensations
    earning_types: EarningTypes
    contractors: Contractors
    contractor_payment_methods: ContractorPaymentMethods
    contractor_payment_method: ContractorPaymentMethodSDK
    webhooks: Webhooks
    webhook_subscriptions: WebhookSubscriptions
    contractor_forms: ContractorForms
    contractor_documents: ContractorDocuments
    employee_forms: EmployeeForms
    payrolls: Payrolls
    contractor_payments: ContractorPayments
    contractor_payment_groups: ContractorPaymentGroups
    company_forms: CompanyForms
    pay_stubs: PayStubs
    generated_documents: GeneratedDocuments
    payrolls_documents: PayrollsDocuments
    reports: Reports
    report_templates: ReportTemplates
    company_benefits: CompanyBenefits
    employee_benefits: EmployeeBenefits
    garnishments: Garnishments
    i_9_verification: I9Verification
    i9_authorizations: I9Authorizations
    tax_requirements: TaxRequirements
    time_off_policies: TimeOffPolicies
    holiday_pay_policies: HolidayPayPolicies
    notifications: Notifications
    events: Events
    recovery_cases: RecoveryCases
    ach_transactions: ACHTransactions
    wire_in_requests: WireInRequests

    def __init__(
        self,
        company_access_auth: Optional[
            Union[Optional[str], Callable[[], Optional[str]]]
        ] = None,
        server: Optional[str] = None,
        server_url: Optional[str] = None,
        url_params: Optional[Dict[str, str]] = None,
        client: Optional[HttpClient] = None,
        async_client: Optional[AsyncHttpClient] = None,
        retry_config: OptionalNullable[RetryConfig] = UNSET,
        timeout_ms: Optional[int] = None,
        debug_logger: Optional[Logger] = None,
    ) -> None:
        r"""Instantiates the SDK configuring it with the provided parameters.

        :param company_access_auth: The company_access_auth required for authentication
        :param server: The server by name to use for all methods
        :param server_url: The server URL to use for all methods
        :param url_params: Parameters to optionally template the server URL with
        :param client: The HTTP client to use for all synchronous methods
        :param async_client: The Async HTTP client to use for all asynchronous methods
        :param retry_config: The retry configuration to use for all supported methods
        :param timeout_ms: Optional request timeout applied to each operation in milliseconds
        """
        if client is None:
            client = httpx.Client()

        assert issubclass(
            type(client), HttpClient
        ), "The provided client must implement the HttpClient protocol."

        if async_client is None:
            async_client = httpx.AsyncClient()

        if debug_logger is None:
            debug_logger = get_default_logger()

        assert issubclass(
            type(async_client), AsyncHttpClient
        ), "The provided async_client must implement the AsyncHttpClient protocol."

        security: Any = None
        if callable(company_access_auth):
            # pylint: disable=unnecessary-lambda-assignment
            security = lambda: models.Security(
                company_access_auth=company_access_auth()
            )
        else:
            security = models.Security(company_access_auth=company_access_auth)

        if server_url is not None:
            if url_params is not None:
                server_url = utils.template_url(server_url, url_params)

        BaseSDK.__init__(
            self,
            SDKConfiguration(
                client=client,
                async_client=async_client,
                security=security,
                server_url=server_url,
                server=server,
                retry_config=retry_config,
                timeout_ms=timeout_ms,
                debug_logger=debug_logger,
            ),
        )

        hooks = SDKHooks()

        current_server_url, *_ = self.sdk_configuration.get_server_details()
        server_url, self.sdk_configuration.client = hooks.sdk_init(
            current_server_url, self.sdk_configuration.client
        )
        if current_server_url != server_url:
            self.sdk_configuration.server_url = server_url

        # pylint: disable=protected-access
        self.sdk_configuration.__dict__["_hooks"] = hooks

        weakref.finalize(
            self,
            close_clients,
            cast(ClientOwner, self.sdk_configuration),
            self.sdk_configuration.client,
            self.sdk_configuration.async_client,
        )

        self._init_sdks()

    def _init_sdks(self):
        self.introspection = Introspection(self.sdk_configuration)
        self.companies = Companies(self.sdk_configuration)
        self.invoices = Invoices(self.sdk_configuration)
        self.company_attachment = CompanyAttachmentSDK(self.sdk_configuration)
        self.company_federal_taxes = CompanyFederalTaxes(self.sdk_configuration)
        self.federal_tax_details = FederalTaxDetailsSDK(self.sdk_configuration)
        self.industry_selections = IndustrySelections(self.sdk_configuration)
        self.signatories = Signatories(self.sdk_configuration)
        self.flows = Flows(self.sdk_configuration)
        self.locations = Locations(self.sdk_configuration)
        self.bank_accounts = BankAccounts(self.sdk_configuration)
        self.external_payrolls = ExternalPayrolls(self.sdk_configuration)
        self.payment_configs = PaymentConfigsSDK(self.sdk_configuration)
        self.pay_schedules = PaySchedules(self.sdk_configuration)
        self.employees = Employees(self.sdk_configuration)
        self.departments = Departments(self.sdk_configuration)
        self.employee_terminations = EmployeeTerminations(self.sdk_configuration)
        self.employee_employments = EmployeeEmployments(self.sdk_configuration)
        self.terminations = Terminations(self.sdk_configuration)
        self.employee_addresses = EmployeeAddresses(self.sdk_configuration)
        self.home_addresses = HomeAddresses(self.sdk_configuration)
        self.work_addresses = WorkAddresses(self.sdk_configuration)
        self.employee_onboarding = EmployeeOnboarding(self.sdk_configuration)
        self.employee_tax_setup = EmployeeTaxSetup(self.sdk_configuration)
        self.employee_taxes = EmployeeTaxes(self.sdk_configuration)
        self.employee_payment_methods = EmployeePaymentMethods(self.sdk_configuration)
        self.employee_payment_method = EmployeePaymentMethodSDK(self.sdk_configuration)
        self.employee_bank_accounts = EmployeeBankAccounts(self.sdk_configuration)
        self.jobs_and_compensations = JobsAndCompensations(self.sdk_configuration)
        self.jobs = Jobs(self.sdk_configuration)
        self.job_compensations = JobCompensations(self.sdk_configuration)
        self.compensations = Compensations(self.sdk_configuration)
        self.earning_types = EarningTypes(self.sdk_configuration)
        self.contractors = Contractors(self.sdk_configuration)
        self.contractor_payment_methods = ContractorPaymentMethods(
            self.sdk_configuration
        )
        self.contractor_payment_method = ContractorPaymentMethodSDK(
            self.sdk_configuration
        )
        self.webhooks = Webhooks(self.sdk_configuration)
        self.webhook_subscriptions = WebhookSubscriptions(self.sdk_configuration)
        self.contractor_forms = ContractorForms(self.sdk_configuration)
        self.contractor_documents = ContractorDocuments(self.sdk_configuration)
        self.employee_forms = EmployeeForms(self.sdk_configuration)
        self.payrolls = Payrolls(self.sdk_configuration)
        self.contractor_payments = ContractorPayments(self.sdk_configuration)
        self.contractor_payment_groups = ContractorPaymentGroups(self.sdk_configuration)
        self.company_forms = CompanyForms(self.sdk_configuration)
        self.pay_stubs = PayStubs(self.sdk_configuration)
        self.generated_documents = GeneratedDocuments(self.sdk_configuration)
        self.payrolls_documents = PayrollsDocuments(self.sdk_configuration)
        self.reports = Reports(self.sdk_configuration)
        self.report_templates = ReportTemplates(self.sdk_configuration)
        self.company_benefits = CompanyBenefits(self.sdk_configuration)
        self.employee_benefits = EmployeeBenefits(self.sdk_configuration)
        self.garnishments = Garnishments(self.sdk_configuration)
        self.i_9_verification = I9Verification(self.sdk_configuration)
        self.i9_authorizations = I9Authorizations(self.sdk_configuration)
        self.tax_requirements = TaxRequirements(self.sdk_configuration)
        self.time_off_policies = TimeOffPolicies(self.sdk_configuration)
        self.holiday_pay_policies = HolidayPayPolicies(self.sdk_configuration)
        self.notifications = Notifications(self.sdk_configuration)
        self.events = Events(self.sdk_configuration)
        self.recovery_cases = RecoveryCases(self.sdk_configuration)
        self.ach_transactions = ACHTransactions(self.sdk_configuration)
        self.wire_in_requests = WireInRequests(self.sdk_configuration)

    def __enter__(self):
        return self

    async def __aenter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.sdk_configuration.client is not None:
            self.sdk_configuration.client.close()

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if self.sdk_configuration.async_client is not None:
            await self.sdk_configuration.async_client.aclose()
