package executor

import (
	"context"

	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/cql/parser"
)

func (e *Executor) resolveTableName(ctx context.Context, user, password string, table *parser.TableName) error {
	if e.schemaManager == nil || table == nil || table.Schema == "" || table.Name == "" {
		return nil
	}
	info, ok, err := e.schemaManager.ResolveTable(ctx, user, password, table.Schema, table.Name)
	if err != nil {
		return err
	}
	if ok {
		table.Schema = info.Schema
		table.Name = info.Name
	}
	return nil
}

func (e *Executor) resolveStatementTables(ctx context.Context, user, password string, stmt parser.Statement) error {
	if stmt == nil || e.schemaManager == nil {
		return nil
	}
	switch s := stmt.(type) {
	case *parser.SelectStatement:
		return e.resolveTableName(ctx, user, password, s.From)
	case *parser.InsertStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.UpdateStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.DeleteStatement:
		return e.resolveTableName(ctx, user, password, s.From)
	case *parser.DropTableStatement:
		return e.resolveTableName(ctx, user, password, s.Name)
	case *parser.AlterTableStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.TruncateStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.CreateIndexStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.CreateMaterializedViewStatement:
		if s.Select != nil {
			return e.resolveTableName(ctx, user, password, s.Select.From)
		}
		return nil
	case *parser.AlterMaterializedViewStatement:
		return e.resolveTableName(ctx, user, password, s.Name)
	case *parser.DropMaterializedViewStatement:
		return e.resolveTableName(ctx, user, password, s.Name)
	case *parser.CreateTriggerStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.DropTriggerStatement:
		return e.resolveTableName(ctx, user, password, s.Table)
	case *parser.CreateTableLikeStatement:
		return e.resolveTableName(ctx, user, password, s.Source)
	case *parser.BatchStatement:
		for _, entry := range s.Entries {
			if err := e.resolveStatementTables(ctx, user, password, entry); err != nil {
				return err
			}
		}
	}
	return nil
}
