import sys

with open('transformer.go', 'r', encoding='utf-8') as f:
    content = f.read()

# Replacement 1: Add pre-scan loop before the file processing loop
old1 = '\tnewPaths := make([]string, 0, len(files))\n\n\tfor i, file := range files {'
new1 = '''\tnewPaths := make([]string, 0, len(files))

\t// Pre-scan all files to collect //garble:ignore directives before any transformation.
\t// This ensures that if a file using an ignored type is processed before the file
\t// defining it, the name is still preserved.
\tfor _, file := range files {
\t\tfor _, decl := range file.Decls {
\t\t\tif gd, ok := decl.(*ast.GenDecl); ok && gd.Tok == token.TYPE {
\t\t\t\tif hasDocIgnore(gd.Doc) {
\t\t\t\t\tfor _, spec := range gd.Specs {
\t\t\t\t\t\tif ts, ok := spec.(*ast.TypeSpec); ok {
\t\t\t\t\t\t\tif tf.ignoredStructs == nil {
\t\t\t\t\t\t\t\ttf.ignoredStructs = make(map[string]bool)
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\ttf.ignoredStructs[ts.Name.Name] = true
\t\t\t\t\t\t\tif flagDebug {
\t\t\t\t\t\t\t\tlog.Printf("[GARBLE-DEBUG] pre-scan //garble:ignore on type %s", ts.Name.Name)
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t}
\t\t\t\t}
\t\t\t}
\t\t\tif fd, ok := decl.(*ast.FuncDecl); ok {
\t\t\t\tif hasDocIgnore(fd.Doc) {
\t\t\t\t\tif fd.Name != nil {
\t\t\t\t\t\tif tf.ignoredFuncs == nil {
\t\t\t\t\t\t\ttf.ignoredFuncs = make(map[string]bool)
\t\t\t\t\t\t}
\t\t\t\t\t\ttf.ignoredFuncs[fd.Name.Name] = true
\t\t\t\t\t\tif flagDebug {
\t\t\t\t\t\t\tlog.Printf("[GARBLE-DEBUG] pre-scan //garble:ignore on func %s", fd.Name.Name)
\t\t\t\t\t\t}
\t\t\t\t\t}
\t\t\t\t}
\t\t\t}
\t\t}
\t}

\tfor i, file := range files {'''

if old1 not in content:
    print("ERROR: old1 not found")
    sys.exit(1)
content = content.replace(old1, new1, 1)

# Replacement 2: Remove duplicate collection inside the literals block
old2 = '''\t\tfor _, decl := range file.Decls {
\t\t\tif gd, ok := decl.(*ast.GenDecl); ok && gd.Tok == token.TYPE {
\t\t\t\tif hasDocIgnore(gd.Doc) {
\t\t\t\t\tfor _, spec := range gd.Specs {
\t\t\t\t\t\tif ts, ok := spec.(*ast.TypeSpec); ok {
\t\t\t\t\t\t\ttf.ignoredStructs[ts.Name.Name] = true
\t\t\t\t\t\t\tif flagDebug {
\t\t\t\t\t\t\t\tlog.Printf("[GARBLE-DEBUG] //garble:ignore on type %s", ts.Name.Name)
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t}
\t\t\t\t}
\t\t\t}
\t\t}
\t\ttf.useAllImports(file)'''
new2 = '\t\ttf.useAllImports(file)'

if old2 not in content:
    print("ERROR: old2 not found")
    sys.exit(1)
content = content.replace(old2, new2, 1)

# Replacement 3: Remove duplicate collection in the renaming section
old3 = '''\tfor _, decl := range file.Decls {
\t\tif gd, ok := decl.(*ast.GenDecl); ok && gd.Tok == token.TYPE {
\t\t\tif hasDocIgnore(gd.Doc) {
\t\t\t\tfor _, spec := range gd.Specs {
\t\t\t\t\tif ts, ok := spec.(*ast.TypeSpec); ok {
\t\t\t\t\t\tif tf.ignoredStructs == nil {
\t\t\t\t\t\t\ttf.ignoredStructs = make(map[string]bool)
\t\t\t\t\t\t}
\t\t\t\t\t\ttf.ignoredStructs[ts.Name.Name] = true
\t\t\t\t\t\tif flagDebug {
\t\t\t\t\t\t\tlog.Printf("[GARBLE-DEBUG] //garble:ignore on type %s (renaming)", ts.Name.Name)
\t\t\t\t\t\t}
\t\t\t\t\t}
\t\t\t\t}
\t\t\t}
\t\t}
\t\tif fd, ok := decl.(*ast.FuncDecl); ok {
\t\t\tif hasDocIgnore(fd.Doc) {
\t\t\t\tif fd.Name != nil {
\t\t\t\t\tif tf.ignoredFuncs == nil {
\t\t\t\t\t\ttf.ignoredFuncs = make(map[string]bool)
\t\t\t\t\t}
\t\t\t\t\ttf.ignoredFuncs[fd.Name.Name] = true
\t\t\t\t\tif flagDebug {
\t\t\t\t\t\tlog.Printf("[GARBLE-DEBUG] //garble:ignore on func %s (renaming)", fd.Name.Name)
\t\t\t\t\t}
\t\t\t\t}
\t\t\t}
\t\t}
\t}

\tpre := func(cursor *astutil.Cursor) bool {'''
new3 = '\tpre := func(cursor *astutil.Cursor) bool {'

if old3 not in content:
    print("ERROR: old3 not found")
    sys.exit(1)
content = content.replace(old3, new3, 1)

with open('transformer.go', 'w', encoding='utf-8') as f:
    f.write(content)

print("OK")
