#!/bin/bash

# Update PORT tags with allocated ports
portUpdateComposeTags()
{
    local app_name="$1"
    local full_file_path="$2"
    
    local port_tags_found=()
    local port_numbers=()
    
    for i in {1..20}; do
        if grep -q "#LIBREPORTAL|PORTS_TAG_$i|" "$full_file_path" || \
           grep -q "#LIBREPORTAL|PORT_EXTERNAL_TAG_$i|" "$full_file_path" || \
           grep -q "#LIBREPORTAL|PORT_INTERNAL_TAG_$i|" "$full_file_path"; then
            port_tags_found+=("PORTS_TAG_$i")
            port_numbers+=($i)
        fi
    done
    
    if [[ ${#port_tags_found[@]} -eq 0 ]]; then
        isNotice "No port tags found in $full_file_path"
    else
        for i in "${!port_numbers[@]}"; do
        local port_num="${port_numbers[$i]}"
        local port_tag="${port_tags_found[$i]}"
        
        # Find matching port data from pre-parsed arrays
        local port_for_tag=""
        local internal_port_for_tag=""
        local url_accessible_for_tag="false"
        local actual_service_name=""
        local access_type_for_tag=""
        
        for j in "${!port_data_tags[@]}"; do
            if [[ "${port_data_tags[$j]}" == "$port_tag" ]]; then
                portAllocate "$app_name"
                if [[ -z "$allocated_ports" ]]; then
                    isError "Failed to allocate ports for $app_name"
                    continue 2
                fi
                
                # SOH-delimited mappings; split by SOH then by `:` so labels
                # with spaces or commas don't break the parse.
                IFS=$'\x01' read -ra _mappings <<< "$allocated_ports"
                for service_mapping in "${_mappings[@]}"; do
                    IFS=':' read -ra parts <<< "$service_mapping"
                    if [[ ${#parts[@]} -ge 8 && "${parts[1]}" == "$port_tag" ]]; then
                        port_for_tag="${parts[2]}"
                        actual_service_name="${parts[0]}"
                        break
                    fi
                done
                
                # Use pre-parsed data for internal port, url accessibility, traefik management, and access type
                internal_port_for_tag="${port_internal_ports[$j]}"
                url_accessible_for_tag="${port_url_accessibles[$j]}"
                traefik_managed_for_tag="${port_traefik_managed[$j]}"
                access_type_for_tag="${port_access_types[$j]}"
                protocol_for_tag="${port_protocols[$j]}"
                break
            fi
        done
        
        # No allocation for this tag. If the user explicitly marked it
        # `disabled`, we still need to neutralise the unfilled
        # `PORTS_DATA_<n>` placeholder in the compose file — Docker rejects
        # `- "PORTS_DATA_4"` with `invalid containerPort`. Replace the line
        # with a commented-out version so the compose stays valid and the
        # tag is still re-findable if the user later re-enables the port.
        if [[ -z "$port_for_tag" ]]; then
            if [[ "$access_type_for_tag" == "disabled" ]]; then
                runFileOp sed -i 's@^\(\s*\)- "PORTS_DATA_'"$port_num"'" #LIBREPORTAL|'"$port_tag"'@\1# - "PORTS_DATA_'"$port_num"'" #LIBREPORTAL|'"$port_tag"'@g' "$full_file_path"
                isSuccessful "Port $port_tag is disabled — placeholder commented out in compose."
            else
                isNotice "No port allocation found for $port_tag, skipping..."
            fi
            continue
        fi

        # Update port tags. Append `/udp` for udp services so docker
        # publishes the right protocol — wireguard etc. break silently
        # otherwise because docker defaults to tcp.
        local combined_port="${port_for_tag}:${internal_port_for_tag}"
        if [[ "$protocol_for_tag" == "udp" ]]; then
            combined_port="${combined_port}/udp"
        fi
        
        # Normal port tag update (always update the tags first)
        tagsManagerUpdateUniversalTag "$full_file_path" "PORTS_TAG_$port_num" "$combined_port"
        tagsManagerUpdateUniversalTag "$full_file_path" "PORT_EXTERNAL_TAG_$port_num" "$port_for_tag"
        tagsManagerUpdateUniversalTag "$full_file_path" "PORT_INTERNAL_TAG_$port_num" "$internal_port_for_tag"
        
        # Check if access type is disabled - if so, comment out the port line after updating
        if [[ "$access_type_for_tag" == "disabled" ]]; then
            # Comment out the port line in docker-compose.yml using the actual port data
            runFileOp sed -i 's@      - "'"$combined_port"'" #LIBREPORTAL|'"$port_tag"'@      # - "'"$combined_port"'" #LIBREPORTAL|'"$port_tag"'@g' "$full_file_path"
            isSuccessful "Port $port_tag has been disabled as per config"
        else
            # Uncomment the port line if it was previously disabled
            runFileOp sed -i 's@      # - "'"$combined_port"'" #LIBREPORTAL|'"$port_tag"'@      - "'"$combined_port"'" #LIBREPORTAL|'"$port_tag"'@g' "$full_file_path"
            isSuccessful "Port $port_tag has been enabled as per config"
        fi

        # Use actual service name or fallback
        local db_service_name="${actual_service_name:-service_${port_num}}"
        
        # Only log to database if port is not disabled
        if [[ "$access_type_for_tag" != "disabled" ]]; then
            # Log to database
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'port_tag_combined', '$combined_port', '$db_service_name', 'active', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'port_tag_external', '$port_for_tag', '$db_service_name', 'active', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'port_tag_internal', '$internal_port_for_tag', '$db_service_name', 'active', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'traefik_managed', '$traefik_managed_for_tag', '$db_service_name', 'active', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'url_accessible', '$url_accessible_for_tag', '$db_service_name', 'active', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
        else
            # Log disabled port with 'disabled' status
            runInstallOp sqlite3 "$docker_dir/$db_file" "INSERT OR REPLACE INTO network_resources (app_name, resource_type, resource_value, service_name, status, created_date, created_time) VALUES ('$app_name', 'port_tag_combined', '$combined_port', '$db_service_name', 'disabled', CURRENT_DATE, CURRENT_TIME);" 2>/dev/null
        fi
    done
    
        isSuccessful "Updated ${#port_tags_found[@]} port tag sets."
    fi
}
