
"""Common Utility Module.

This module provides common utilities, enums, decorators, and helper functions used
throughout the JL Automation platform. It includes definitions for audit statuses,
entity types, report statuses, and various utility functions for data validation
and transformation.

Key Components:
    - Enums for audit actions, statuses, and entity types
    - Deprecation decorator for marking legacy functions
    - Report status tracking
    - Timezone conversion utilities
    - Common exception classes
"""

from warnings import warn
from functools import wraps
from typing import Callable
from enum import IntEnum, Enum

def deprecated(message: str) -> Callable:
    """Decorator to mark functions as deprecated with a custom warning message.
    
    This decorator issues a DeprecationWarning when the decorated function is called,
    helping developers identify and migrate away from legacy functionality.
    
    Args:
        message (str): Custom deprecation message to display.
        
    Returns:
        Callable: Decorator function that wraps the target function.
        
    Example:
        @deprecated("This function will be removed in v2.0. Use new_function() instead.")
        async def old_function():
            pass
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args, **kwargs):
            warn(message, DeprecationWarning, stacklevel=2)
            return await func(*args, **kwargs)
        return wrapper
    return decorator

class ReportStatus(IntEnum):
    """Enumeration for report generation status tracking.
    
    This enum defines the possible states of a report generation process,
    allowing for proper status tracking and conditional logic.
    """
    NOT_STARTED = 0
    RUNNING = 1
    SUCCEEDED = 2
    FAILED = 3


class AuditStatus(Enum):
    """Enumeration for audit operation status.
    
    This enum defines the success or failure status of audit operations,
    using boolean values for easy conditional checking.
    """
    SUCCESS = True
    FAILURE = False


class AuditAction(IntEnum):
    """Enumeration for types of audit actions performed on entities.
    
    This enum defines the different types of operations that can be
    performed on entities and tracked in the audit system.
    """
    CREATE = 1
    UPDATE = 2
    DELETE = 3


class EntityType(IntEnum):
    """Enumeration for all entity types in the JL system.
    
    This comprehensive enum defines all the different types of entities
    that can be managed, audited, and tracked within the platform.
    Each entity type has a unique identifier for database operations
    and audit trail management.
    """
    Root = 0
    Customer = 1
    Site = 2
    Job = 3
    Visit = 4
    Contact = 5
    VisitExpense = 6
    VisitTime = 7
    VisitPart = 8
    VisitSignature = 9
    VisitMobileForm = 10
    VisitStatusAudit = 11
    VisitNote = 12
    VisitAttachment = 13
    JobAttachment = 14
    JobNote = 15
    JobLine = 16
    Invoice = 17
    JobAsset = 18
    JobStatusAudit = 19
    JobTask = 20
    SiteNote = 21
    SiteAttachment = 22
    SiteAsset = 23
    Quote = 24
    CustomerAttachment = 25
    CustomerNote = 26
    CustomerContact = 27
    SiteContact = 28
    JobContact = 29
    PPMContract = 30
    PPMContractVisit = 31
    PPMContractInvoice = 32
    QuoteAttachment = 33
    QuoteNote = 34
    QuoteLine = 35
    Credit = 36
    InvoiceLine = 38
    WebLogicUser = 39
    CustomerSellingRate = 40
    SiteSellingRate = 41
    CompanySellingRate = 42
    LogBook = 43
    LeakCheck = 44
    User = 46
    Part = 47
    SellingRate = 48
    Tasks = 49
    ServiceType = 50
    TaxRates = 51
    NominaCode = 52
    Misc = 53
    AssetAttachment = 54
    AdditionRemovalReason = 55
    UserAttachment = 56
    UserNote = 57
    CreditLine = 58
    LibraryItem = 59
    PPMContractNote = 60
    PPMContractAttachment = 61
    GasCylinder = 62
    Supplier = 63
    AuditData = 64
    PurchaseOrder = 65
    PurchaseOrderLine = 66
    PurchaseOrderSupplierInvoice = 67
    Priority = 68
    GasCylinderTransaction = 69
    TaxCode = 70
    PPMContractFixedPriceInvoices = 71
    Tag = 72
    Payment = 73
    RelatedJobs = 74
    DocumentTemplates = 75
    RelatedAssets = 77
    QuoteContact = 78
    NonProductiveTimeType = 79
    NonProductiveTime = 80
    Company = 81
    CompanyForms = 82
    Discount = 83
    Source = 84
    Report = 85
    RelatedQuotes = 86
    QuoteRejectReason = 87
    FormsLogbook = 88
    AssetNote = 89
    Trade = 90
    PayBand = 91
    PayBandTime = 92
    DynamicDashboard = 93
    CompanyDocument = 94
    DocumentTypes = 95
    RelatedSite = 96
    SupplierBranch = 97
    SupplierPart = 98
    SupplierEquipment = 99
    Authorisation = 100
    Bulletin = 101
    PPMContractCredit = 102
    CustomForm = 103
    PPMContractSchedule = 104
    Subcontractor = 105
    PPMContract_InvoiceHeader = 106
    Tap = 107
    PurchaseOrderAttachment = 108
    PurchaseOrderNote = 109
    SupplierAttachment = 110
    SupplierNote = 111
    RouteSchedule = 112
    CustomerGroupedInvoice = 113
    CustomerGroupedCredit = 114
    CustomerGroupedInvoiceLine = 115
    CustomerGroupedCreditLine = 116
    CustomerGroupedInvoicePayment = 117
    PPMContractInvoiceLine = 118
    PPMContractCreditLine = 119
    PPMContractInvoicePayment = 120
    ContactLevel = 121
    ServiceTypeLine = 122
    JobQuickFilter = 123
    NotificationUser = 124
    EngineerTrade = 125
    QuoteAsset = 126
    BaseNote = 127
    BaseAttachment = 128
    Vehicle = 129
    Location = 130
    VehicleNote = 131
    VehicleAttachment = 132
    RackShelf = 133
    PurchaseOrderTemplate = 134
    PurchaseOrderTemplateItem = 135
    Equipment = 136
    QuoteTemplate = 137
    AssetCondition = 138
    Stock = 140
    StockLocation = 141
    SecondaryJobTrade = 142
    StockTake = 143
    ReportTemplate = 144
    Role = 145
    EngineerDocument = 146
    SubcontractorDocument = 147
    JobForm = 148
    GroupPriority = 149
    PPMQuote = 150
    TradeCategory = 151
    ScheduleOfRateLibrary = 152
    ScheduleOfRateItem = 153
    QuickFilter = 154
    Signature = 155
    PPMQuoteSchedule = 156
    Area = 157
    Expense = 158
    GeneralMobileForm = 159
    ToDo = 160
    PurchaseOrderSubContractorInvoice = 161
    PurchaseOrderSubContractorInvoiceLine = 162
    SubContractorPurchaseOrder = 163
    SubContractorPurchaseOrderNote = 164
    SubContractorPurchaseOrderAttachment = 165
    SubContractorPurchaseOrderLine = 166
    SubContractorArea = 167
    SubContractorTrade = 168
    SubContractorJobAllocation = 169
    SubContractorJobAllocationAttachment = 170
    SubContractorJobAllocationNote = 171
    SubContractorJobAllocationDetail = 172
    SubContractorJobAllocationDetailAttachment = 173
    SubContractorJobAllocationDetailNote = 174
    BaseApprovalNote = 175
    PPMQuote_InvoiceHeader = 180
    PPMQuoteNote = 181
    TeamArea = 182
    TeamTrade = 183
    TeamClass = 184
    TeamMember = 185
    EngineerTeam = 186
    SubcontractorTemplate = 187
    MainContractorNote = 188
    SubContractorPurchaseOrderResolved = 189
    VirtualVisit = 191
    PartLibrary = 192
    AssetClass = 193
    PartCategory = 194
    BatchInvoice = 195
    StockAdjustment = 196
    NPTRecurSetting = 197
    JobTemplate = 198
    ServiceJob = 199
    CustomerServiceJob = 200
    SiteService = 201
    SiteServiceAsset = 202
    ServiceLetter = 203
    SubContractorPurchaseOrderArea = 204
    SubContractorPurchaseOrderTrade = 205
    PlannerRouteVisitDetail = 206
    JLMarketplaceApp = 207
    Engineer = 208

class ReportRequestError(Exception):
    """Raised when report request fails"""
    pass

class ReportStatusError(Exception):
    """Raised when report status check fails"""
    pass

WINDOWS_TO_IANA = {
    "Dateline Standard Time": "Etc/GMT+12",
    "UTC-11": "Etc/GMT+11",
    "Aleutian Standard Time": "America/Adak",
    "Hawaiian Standard Time": "Pacific/Honolulu",
    "Marquesas Standard Time": "Pacific/Marquesas",
    "Alaskan Standard Time": "America/Anchorage",
    "UTC-09": "Etc/GMT+9",
    "Pacific Standard Time (Mexico)": "America/Tijuana",
    "UTC-08": "Etc/GMT+8",
    "Pacific Standard Time": "America/Los_Angeles",
    "US Mountain Standard Time": "America/Phoenix",
    "Mountain Standard Time (Mexico)": "America/Chihuahua",
    "Mountain Standard Time": "America/Denver",
    "Yukon Standard Time": "America/Whitehorse",
    "Central America Standard Time": "America/Guatemala",
    "Central Standard Time": "America/Chicago",
    "Easter Island Standard Time": "Pacific/Easter",
    "Central Standard Time (Mexico)": "America/Mexico_City",
    "Canada Central Standard Time": "America/Regina",
    "SA Pacific Standard Time": "America/Bogota",
    "Eastern Standard Time (Mexico)": "America/Cancun",
    "Eastern Standard Time": "America/New_York",
    "Haiti Standard Time": "America/Port-au-Prince",
    "Cuba Standard Time": "America/Havana",
    "US Eastern Standard Time": "America/Indiana/Indianapolis",
    "Turks And Caicos Standard Time": "America/Grand_Turk",
    "Paraguay Standard Time": "America/Asuncion",
    "Atlantic Standard Time": "America/Halifax",
    "Venezuela Standard Time": "America/Caracas",
    "Central Brazilian Standard Time": "America/Cuiaba",
    "SA Western Standard Time": "America/La_Paz",
    "Pacific SA Standard Time": "America/Santiago",
    "Newfoundland Standard Time": "America/St_Johns",
    "Tocantins Standard Time": "America/Araguaina",
    "E. South America Standard Time": "America/Sao_Paulo",
    "SA Eastern Standard Time": "America/Cayenne",
    "Argentina Standard Time": "America/Argentina/Buenos_Aires",
    "Montevideo Standard Time": "America/Montevideo",
    "Magallanes Standard Time": "America/Punta_Arenas",
    "Saint Pierre Standard Time": "America/Miquelon",
    "Bahia Standard Time": "America/Bahia",
    "UTC-02": "Etc/GMT+2",
    "Greenland Standard Time": "America/Godthab",
    "Mid-Atlantic Standard Time": "Etc/GMT+2",
    "Azores Standard Time": "Atlantic/Azores",
    "Cape Verde Standard Time": "Atlantic/Cape_Verde",
    "UTC": "Etc/UTC",
    "GMT Standard Time": "Europe/London",
    "Greenwich Standard Time": "Etc/GMT",
    "Sao Tome Standard Time": "Africa/Sao_Tome",
    "Morocco Standard Time": "Africa/Casablanca",
    "W. Europe Standard Time": "Europe/Berlin",
    "Central Europe Standard Time": "Europe/Budapest",
    "Romance Standard Time": "Europe/Paris",
    "Central European Standard Time": "Europe/Warsaw",
    "W. Central Africa Standard Time": "Africa/Lagos",
    "GTB Standard Time": "Europe/Bucharest",
    "Middle East Standard Time": "Asia/Beirut",
    "Egypt Standard Time": "Africa/Cairo",
    "E. Europe Standard Time": "Europe/Chisinau",
    "West Bank Standard Time": "Asia/Hebron",
    "South Africa Standard Time": "Africa/Johannesburg",
    "FLE Standard Time": "Europe/Kiev",
    "Israel Standard Time": "Asia/Jerusalem",
    "South Sudan Standard Time": "Africa/Juba",
    "Kaliningrad Standard Time": "Europe/Kaliningrad",
    "Sudan Standard Time": "Africa/Khartoum",
    "Libya Standard Time": "Africa/Tripoli",
    "Namibia Standard Time": "Africa/Windhoek",
    "Jordan Standard Time": "Asia/Amman",
    "Arabic Standard Time": "Asia/Baghdad",
    "Syria Standard Time": "Asia/Damascus",
    "Turkey Standard Time": "Europe/Istanbul",
    "Arab Standard Time": "Asia/Riyadh",
    "Belarus Standard Time": "Europe/Minsk",
    "Russian Standard Time": "Europe/Moscow",
    "E. Africa Standard Time": "Africa/Nairobi",
    "Volgograd Standard Time": "Europe/Volgograd",
    "Iran Standard Time": "Asia/Tehran",
    "Arabian Standard Time": "Asia/Dubai",
    "Astrakhan Standard Time": "Europe/Astrakhan",
    "Azerbaijan Standard Time": "Asia/Baku",
    "Russia Time Zone 3": "Europe/Samara",
    "Mauritius Standard Time": "Indian/Mauritius",
    "Saratov Standard Time": "Europe/Saratov",
    "Georgian Standard Time": "Asia/Tbilisi",
    "Caucasus Standard Time": "Asia/Yerevan",
    "Afghanistan Standard Time": "Asia/Kabul",
    "West Asia Standard Time": "Asia/Tashkent",
    "Qyzylorda Standard Time": "Asia/Qyzylorda",
    "Ekaterinburg Standard Time": "Asia/Yekaterinburg",
    "Pakistan Standard Time": "Asia/Karachi",
    "India Standard Time": "Asia/Kolkata",
    "Sri Lanka Standard Time": "Asia/Colombo",
    "Nepal Standard Time": "Asia/Kathmandu",
    "Central Asia Standard Time": "Asia/Almaty",
    "Bangladesh Standard Time": "Asia/Dhaka",
    "Omsk Standard Time": "Asia/Omsk",
    "Myanmar Standard Time": "Asia/Yangon",
    "SE Asia Standard Time": "Asia/Bangkok",
    "Altai Standard Time": "Asia/Barnaul",
    "W. Mongolia Standard Time": "Asia/Hovd",
    "North Asia Standard Time": "Asia/Krasnoyarsk",
    "N. Central Asia Standard Time": "Asia/Novosibirsk",
    "Tomsk Standard Time": "Asia/Tomsk",
    "China Standard Time": "Asia/Shanghai",
    "North Asia East Standard Time": "Asia/Irkutsk",
    "Singapore Standard Time": "Asia/Singapore",
    "W. Australia Standard Time": "Australia/Perth",
    "Taipei Standard Time": "Asia/Taipei",
    "Ulaanbaatar Standard Time": "Asia/Ulaanbaatar",
    "Aus Central W. Standard Time": "Australia/Eucla",
    "Transbaikal Standard Time": "Asia/Chita",
    "Tokyo Standard Time": "Asia/Tokyo",
    "North Korea Standard Time": "Asia/Pyongyang",
    "Korea Standard Time": "Asia/Seoul",
    "Yakutsk Standard Time": "Asia/Yakutsk",
    "Cen. Australia Standard Time": "Australia/Adelaide",
    "AUS Central Standard Time": "Australia/Darwin",
    "E. Australia Standard Time": "Australia/Brisbane",
    "AUS Eastern Standard Time": "Australia/Sydney",
    "West Pacific Standard Time": "Pacific/Port_Moresby",
    "Tasmania Standard Time": "Australia/Hobart",
    "Vladivostok Standard Time": "Asia/Vladivostok",
    "Lord Howe Standard Time": "Australia/Lord_Howe",
    "Bougainville Standard Time": "Pacific/Bougainville",
    "Russia Time Zone 10": "Asia/Srednekolymsk",
    "Magadan Standard Time": "Asia/Magadan",
    "Norfolk Standard Time": "Pacific/Norfolk",
    "Sakhalin Standard Time": "Asia/Sakhalin",
    "Central Pacific Standard Time": "Pacific/Guadalcanal",
    "Russia Time Zone 11": "Asia/Kamchatka",
    "New Zealand Standard Time": "Pacific/Auckland",
    "UTC+12": "Etc/GMT-12",
    "Fiji Standard Time": "Pacific/Fiji",
    "Kamchatka Standard Time": "Asia/Kamchatka",
    "Chatham Islands Standard Time": "Pacific/Chatham",
    "UTC+13": "Etc/GMT-13",
    "Tonga Standard Time": "Pacific/Tongatapu",
    "Samoa Standard Time": "Pacific/Apia",
    "Line Islands Standard Time": "Pacific/Kiritimati",
}