File size: 7,452 Bytes
beb8990
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""
Validation utilities for Calendar API
Provides common validation functions used across different API endpoints
"""

from typing import Optional, Tuple
from database.managers.color_manager import ColorManager
from apis.colors.data import CALENDAR_COLORS, EVENT_COLORS


def validate_calendar_color_id(color_id: Optional[str], database_id: str) -> Optional[str]:
    """
    Validate calendar colorId against database
    
    Args:
        color_id: The color ID to validate (can be None)
        database_id: Database ID for color manager
        
    Returns:
        None if validation passes, error message if invalid
    """
    if color_id is None:
        return None  # Optional field, None is valid
    
    if not isinstance(color_id, str):
        return "colorId must be a string"
    
    try:
        color_manager = ColorManager(database_id)
        if not color_manager.validate_color_id("calendar", color_id):
            return f"Invalid calendar colorId: '{color_id}'. Check available colorId with GET /colors"
    except Exception:
        # Fallback validation if database fails
        return f"Could not validate colorId: '{color_id}'. Database may not be initialized"
    
    return None


def validate_event_color_id(color_id: Optional[str], database_id: str) -> Optional[str]:
    """
    Validate event colorId against database
    
    Args:
        color_id: The color ID to validate (can be None)
        database_id: Database ID for color manager
        
    Returns:
        None if validation passes, error message if invalid
    """
    if color_id is None:
        return None  # Optional field, None is valid
    
    if not isinstance(color_id, str):
        return "colorId must be a string"
    
    try:
        color_manager = ColorManager(database_id)
        if not color_manager.validate_color_id("event", color_id):
            return f"Invalid event colorId: '{color_id}'. Check available colors with GET /colors"
    except Exception:
        # Fallback validation if database fails
        return f"Could not validate colorId: '{color_id}'. Database may not be initialized"
    
    return None


def validate_request_colors(data: dict, color_type: str, database_id: str) -> Optional[str]:
    """
    Validate colorId in request data against database
    
    Args:
        data: Request data dictionary
        color_type: Either 'calendar' or 'event'
        database_id: Database ID for color manager
        
    Returns:
        None if validation passes, error message if invalid
    """
    if "colorId" not in data:
        return None  # No colorId in request, that's fine
    
    color_id = data.get("colorId")
    
    if color_type == "calendar":
        return validate_calendar_color_id(color_id, database_id)
    elif color_type == "event":
        return validate_event_color_id(color_id, database_id)
    else:
        return f"Unknown color type: {color_type}"


def validate_color_combination(background_color: str, foreground_color: str, color_type: str) -> Optional[str]:
    """
    Validate that backgroundColor and foregroundColor combination exists in color data
    
    Args:
        background_color: Background color in hex format (e.g., "#ac725e")
        foreground_color: Foreground color in hex format (e.g., "#1d1d1d")
        color_type: Either 'calendar' or 'event'
        
    Returns:
        None if combination is valid, error message if invalid
    """
    if color_type == "calendar":
        colors = CALENDAR_COLORS
    elif color_type == "event":
        colors = EVENT_COLORS
    else:
        return f"Unknown color type: {color_type}"
    
    # Check if the combination exists in the color data
    for color_id, color_data in colors.items():
        if (color_data["background"].lower() == background_color.lower() and
            color_data["foreground"].lower() == foreground_color.lower()):
            return None  # Valid combination found
    
    return f"Invalid color combination: backgroundColor='{background_color}' and foregroundColor='{foreground_color}' is not a valid {color_type} color combination"


def find_color_id_by_combination(background_color: str, foreground_color: str, color_type: str) -> Optional[str]:
    """
    Find the colorId that matches the given backgroundColor and foregroundColor combination
    
    Args:
        background_color: Background color in hex format (e.g., "#ac725e")
        foreground_color: Foreground color in hex format (e.g., "#1d1d1d")
        color_type: Either 'calendar' or 'event'
        
    Returns:
        colorId if combination is found, None if not found
    """
    if color_type == "calendar":
        colors = CALENDAR_COLORS
    elif color_type == "event":
        colors = EVENT_COLORS
    else:
        return None
    
    # Find the colorId that matches the combination
    for color_id, color_data in colors.items():
        if (color_data["background"].lower() == background_color.lower() and
            color_data["foreground"].lower() == foreground_color.lower()):
            return color_id
    
    return None


def set_colors_from_color_id(data: dict, color_type: str) -> Optional[str]:
    """
    Set backgroundColor and foregroundColor from colorId if they are not provided
    
    Args:
        data: Request data dictionary (will be modified to add colors if colorId is valid)
        color_type: Either 'calendar' or 'event'
        
    Returns:
        None if successful, error message if colorId is invalid
    """
    color_id = data.get("colorId")
    
    # Only process if colorId is provided and RGB colors are not provided
    if not color_id:
        return None
    
    # Skip if RGB colors are already provided
    if data.get("backgroundColor") or data.get("foregroundColor"):
        return None
    
    if color_type == "calendar":
        colors = CALENDAR_COLORS
    elif color_type == "event":
        colors = EVENT_COLORS
    else:
        return f"Unknown color type: {color_type}"
    
    # Validate colorId and get colors
    if color_id not in colors:
        return f"Invalid {color_type} colorId: '{color_id}'. Check available colorId with GET /colors"
    
    # Set the colors from the colorId
    color_data = colors[color_id]
    data["backgroundColor"] = color_data["background"]
    data["foregroundColor"] = color_data["foreground"]
    
    return None


def validate_and_set_color_id(data: dict, color_type: str) -> Optional[str]:
    """
    Validate RGB color combination and set appropriate colorId if valid combination exists
    
    Args:
        data: Request data dictionary (will be modified to add colorId if found)
        color_type: Either 'calendar' or 'event'
        
    Returns:
        None if validation passes, error message if invalid combination
    """
    background_color = data.get("backgroundColor")
    foreground_color = data.get("foregroundColor")
    
    # Only validate if both colors are provided
    if not (background_color and foreground_color):
        return None
    
    # Validate the combination exists
    validation_error = validate_color_combination(background_color, foreground_color, color_type)
    if validation_error:
        return validation_error
    
    # Find and set the matching colorId
    color_id = find_color_id_by_combination(background_color, foreground_color, color_type)
    if color_id:
        data["colorId"] = color_id
    
    return None