package d2svg

import (
	
	

	
	
	
	
)

// validateRenderPaints keeps raw render targets within the same paint grammar
// as compiler-produced targets. In particular, arbitrary CSS paint servers such
// as url(https://example.com/paint.svg) must not reach an SVG attribute.
func validateRenderPaints( *d2target.Diagram,  *RenderOpts) error {
	if  := validatePaint(.Root.Fill, "root fill");  != nil {
		return 
	}
	if  := validatePaint(.Root.Stroke, "root stroke");  != nil {
		return 
	}
	if  := validateFillPattern(.Root.FillPattern, "root fill pattern");  != nil {
		return 
	}

	for  := range .Shapes {
		if  := validateShapePaints(&.Shapes[], fmt.Sprintf("shape %q", .Shapes[].ID));  != nil {
			return 
		}
	}
	for  := range .Connections {
		if  := validateConnectionPaints(&.Connections[], fmt.Sprintf("connection %q", .Connections[].ID));  != nil {
			return 
		}
	}
	if .Legend != nil {
		for  := range .Legend.Shapes {
			if  := validateShapePaints(&.Legend.Shapes[], fmt.Sprintf("legend shape %q", .Legend.Shapes[].ID));  != nil {
				return 
			}
		}
		for  := range .Legend.Connections {
			 := &.Legend.Connections[]
			 := fmt.Sprintf("legend connection %q", .ID)
			if  := validatePaint(.Stroke, +" stroke");  != nil {
				return 
			}
			if  := validatePaint(.Fill, +" fill");  != nil {
				return 
			}
		}
	}

	if  != nil {
		if  := validateThemeOverrides(.ThemeOverrides, "theme override");  != nil {
			return 
		}
		if  := validateThemeOverrides(.DarkThemeOverrides, "dark theme override");  != nil {
			return 
		}
	}
	return nil
}

func validateShapePaints( *d2target.Shape,  string) error {
	for ,  := range []struct {
		  string
		 string
	}{
		{: "fill", : .Fill},
		{: "stroke", : .Stroke},
		{: "font color", : .Color},
		{: "label fill", : .LabelFill},
		{: "primary accent color", : .PrimaryAccentColor},
		{: "secondary accent color", : .SecondaryAccentColor},
		{: "neutral accent color", : .NeutralAccentColor},
	} {
		if  := validatePaint(., +" "+.);  != nil {
			return 
		}
	}
	return validateFillPattern(.FillPattern, +" fill pattern")
}

func validateConnectionPaints( *d2target.Connection,  string) error {
	for ,  := range []struct {
		  string
		 string
	}{
		{: "stroke", : .Stroke},
		{: "fill", : .Fill},
		{: "font color", : .Color},
	} {
		if  := validatePaint(., +" "+.);  != nil {
			return 
		}
	}
	if .SrcLabel != nil {
		if  := validatePaint(.SrcLabel.Color, +" source label color");  != nil {
			return 
		}
	}
	if .DstLabel != nil {
		if  := validatePaint(.DstLabel.Color, +" destination label color");  != nil {
			return 
		}
	}
	return nil
}

func validatePaint(,  string) error {
	if  == "" ||  == color.None || color.IsThemeColor() || color.ValidColor() {
		return nil
	}
	return fmt.Errorf("%s uses unsupported paint %q", , )
}

func validateFillPattern(,  string) error {
	if  == "" || go2.Contains(d2ast.FillPatterns, strings.ToLower()) {
		return nil
	}
	return fmt.Errorf("%s uses unsupported value %q", , )
}

func validateThemeOverrides( *d2target.ThemeOverrides,  string) error {
	if  == nil {
		return nil
	}
	for ,  := range []struct {
		  string
		 *string
	}{
		{: "N1", : .N1},
		{: "N2", : .N2},
		{: "N3", : .N3},
		{: "N4", : .N4},
		{: "N5", : .N5},
		{: "N6", : .N6},
		{: "N7", : .N7},
		{: "B1", : .B1},
		{: "B2", : .B2},
		{: "B3", : .B3},
		{: "B4", : .B4},
		{: "B5", : .B5},
		{: "B6", : .B6},
		{: "AA2", : .AA2},
		{: "AA4", : .AA4},
		{: "AA5", : .AA5},
		{: "AB4", : .AB4},
		{: "AB5", : .AB5},
	} {
		if . == nil {
			continue
		}
		if !go2.Contains(color.NamedColors, strings.ToLower(*.)) && !color.ColorHexRegex.MatchString(*.) {
			return fmt.Errorf("%s %s uses unsupported color %q", , ., *.)
		}
	}
	return nil
}