package ted import ( "bytes" "encoding/xml" "fmt" "strings" "tm/pkg/xmlparser" ) // TEDParser handles parsing of TED XML files type TEDParser struct { contractNoticeParser xmlparser.Parser[ContractNotice] contractAwardNoticeParser xmlparser.Parser[ContractAwardNotice] priorInformationNoticeParser xmlparser.Parser[PriorInformationNotice] designContestParser xmlparser.Parser[DesignContest] qualificationSystemNoticeParser xmlparser.Parser[QualificationSystemNotice] concessionNoticeParser xmlparser.Parser[ConcessionNotice] planningNoticeParser xmlparser.Parser[PlanningNotice] competitionNoticeParser xmlparser.Parser[CompetitionNotice] resultNoticeParser xmlparser.Parser[ResultNotice] changeNoticeParser xmlparser.Parser[ChangeNotice] subcontractNoticeParser xmlparser.Parser[SubcontractNotice] } // NewTEDParser creates a new TED parser func NewTEDParser() *TEDParser { options := xmlparser.DefaultParserOptions() options.MaxSize = 50 * 1024 * 1024 // 50MB limit for TED XML files options.IgnoreUnknownElements = true // TED XML has many optional fields return &TEDParser{ contractNoticeParser: xmlparser.NewParser[ContractNotice](options), contractAwardNoticeParser: xmlparser.NewParser[ContractAwardNotice](options), priorInformationNoticeParser: xmlparser.NewParser[PriorInformationNotice](options), designContestParser: xmlparser.NewParser[DesignContest](options), qualificationSystemNoticeParser: xmlparser.NewParser[QualificationSystemNotice](options), concessionNoticeParser: xmlparser.NewParser[ConcessionNotice](options), planningNoticeParser: xmlparser.NewParser[PlanningNotice](options), competitionNoticeParser: xmlparser.NewParser[CompetitionNotice](options), resultNoticeParser: xmlparser.NewParser[ResultNotice](options), changeNoticeParser: xmlparser.NewParser[ChangeNotice](options), subcontractNoticeParser: xmlparser.NewParser[SubcontractNotice](options), } } // DetectDocumentType detects the type of TED document from XML data func (p *TEDParser) DetectDocumentType(xmlData []byte) (DocumentType, error) { // Fast string-based detection for common patterns xmlStr := string(xmlData) if strings.Contains(xmlStr, "", "", 1) return []byte(xmlStr) } // transformPriorInformationNoticeToContractNotice transforms a PriorInformationNotice XML to ContractNotice format func (p *TEDParser) transformPriorInformationNoticeToContractNotice(xmlData []byte) []byte { return p.transformToContractNotice(xmlData, "PriorInformationNotice") } // Legacy methods for backward compatibility // ParseXMLAsContractNotice parses XML specifically as ContractNotice (legacy method) func (p *TEDParser) ParseXMLAsContractNotice(xmlData []byte) (*ContractNotice, error) { return p.contractNoticeParser.ParseBytes(xmlData) } // ParseXMLAsContractAwardNotice parses XML specifically as ContractAwardNotice func (p *TEDParser) ParseXMLAsContractAwardNotice(xmlData []byte) (*ContractAwardNotice, error) { return p.contractAwardNoticeParser.ParseBytes(xmlData) } // Specific parser methods for all notice types func (p *TEDParser) ParseXMLAsPriorInformationNotice(xmlData []byte) (*PriorInformationNotice, error) { return p.priorInformationNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsDesignContest(xmlData []byte) (*DesignContest, error) { return p.designContestParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsQualificationSystemNotice(xmlData []byte) (*QualificationSystemNotice, error) { return p.qualificationSystemNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsConcessionNotice(xmlData []byte) (*ConcessionNotice, error) { return p.concessionNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsPlanningNotice(xmlData []byte) (*PlanningNotice, error) { return p.planningNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsCompetitionNotice(xmlData []byte) (*CompetitionNotice, error) { return p.competitionNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsResultNotice(xmlData []byte) (*ResultNotice, error) { return p.resultNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsChangeNotice(xmlData []byte) (*ChangeNotice, error) { return p.changeNoticeParser.ParseBytes(xmlData) } func (p *TEDParser) ParseXMLAsSubcontractNotice(xmlData []byte) (*SubcontractNotice, error) { return p.subcontractNoticeParser.ParseBytes(xmlData) }