001package gudusoft.gsqlparser.stmt.teradata;
002
003import gudusoft.gsqlparser.EDbVendor;
004import gudusoft.gsqlparser.TCustomSqlStatement;
005import gudusoft.gsqlparser.nodes.TParseTreeVisitor;
006import gudusoft.gsqlparser.ESqlStatementType;
007
008public class TTeradataMultiLoadExport extends TCustomSqlStatement {
009    private CommandType commandType;
010    private String filePath;
011    private String delimiter = "|";  // default delimiter
012    private String quote = "\"";     // default quote
013    private String encoding = "UTF8"; // default encoding
014    private boolean indicData = false;
015    private Integer width;
016    private String command;
017
018    public enum CommandType {
019        OUTFILE,
020        RESET,
021        UNKNOWN
022    }
023
024    public TTeradataMultiLoadExport(EDbVendor dbvendor, String exportCommand) {
025        super(dbvendor);
026        sqlstatementtype = ESqlStatementType.sstteradataMultiLoadExport;
027        this.command = exportCommand;
028        parse(exportCommand);
029    }
030
031    private void parse(String exportCommand) {
032        if (exportCommand == null || exportCommand.trim().isEmpty()) {
033            throw new IllegalArgumentException("Export command cannot be empty");
034        }
035
036        String command = exportCommand.trim();
037
038        if (!command.startsWith(".EXPORT")) {
039            throw new IllegalArgumentException("Invalid export command format. Must start with .EXPORT");
040        }
041
042        if (command.equals(".EXPORT RESET")) {
043            this.commandType = CommandType.RESET;
044            return;
045        }
046
047        if (command.startsWith(".EXPORT OUTFILE")) {
048            this.commandType = CommandType.OUTFILE;
049            parseOutfileCommand(command);
050        } else {
051            this.commandType = CommandType.UNKNOWN;
052            throw new IllegalArgumentException("Unknown export command type");
053        }
054    }
055
056    private void parseOutfileCommand(String command) {
057        // Remove .EXPORT OUTFILE from the start
058        String options = command.substring(".EXPORT OUTFILE".length()).trim();
059        
060        // Parse each option
061        String[] parts = options.split("\\s+(?=(?:[^'\"]*['\"][^'\"]*['\"])*[^'\"]*$)");
062        
063        for (int i = 0; i < parts.length; i++) {
064            String part = parts[i].trim();
065            
066            if (i == 0) {
067                // First part should be the file path
068                this.filePath = extractQuotedString(part);
069                continue;
070            }
071
072            switch (part.toUpperCase()) {
073                case "DELIMITER":
074                    if (i + 1 < parts.length) {
075                        this.delimiter = extractQuotedString(parts[++i]);
076                    }
077                    break;
078                case "QUOTE":
079                    if (i + 1 < parts.length) {
080                        this.quote = extractQuotedString(parts[++i]);
081                    }
082                    break;
083                case "ENCODING":
084                    if (i + 1 < parts.length) {
085                        this.encoding = extractQuotedString(parts[++i]);
086                    }
087                    break;
088                case "INDICDATA":
089                    this.indicData = true;
090                    break;
091                case "WIDTH":
092                    if (i + 1 < parts.length) {
093                        try {
094                            this.width = Integer.parseInt(parts[++i].replace(";", ""));
095                        } catch (NumberFormatException e) {
096                            throw new IllegalArgumentException("Invalid WIDTH value");
097                        }
098                    }
099                    break;
100            }
101        }
102
103        if (this.filePath == null || this.filePath.isEmpty()) {
104            throw new IllegalArgumentException("File path is required for OUTFILE command");
105        }
106    }
107
108    private String extractQuotedString(String input) {
109        input = input.replace(";", ""); // Remove trailing semicolon if present
110        if (input.startsWith("'") && input.endsWith("'")) {
111            return input.substring(1, input.length() - 1);
112        }
113        if (input.startsWith("\"") && input.endsWith("\"")) {
114            return input.substring(1, input.length() - 1);
115        }
116        return input;
117    }
118
119    public String toCommandString() {
120        if (commandType == CommandType.RESET) {
121            return ".EXPORT RESET;";
122        }
123
124        if (commandType == CommandType.OUTFILE) {
125            StringBuilder command = new StringBuilder();
126            command.append(".EXPORT OUTFILE '").append(filePath).append("'");
127            
128            if (!"|".equals(delimiter)) {
129                command.append(" DELIMITER '").append(delimiter).append("'");
130            }
131            if (!"\"".equals(quote)) {
132                command.append(" QUOTE '").append(quote).append("'");
133            }
134            if (!"UTF8".equals(encoding)) {
135                command.append(" ENCODING '").append(encoding).append("'");
136            }
137            if (indicData) {
138                command.append(" INDICDATA");
139            }
140            if (width != null) {
141                command.append(" WIDTH ").append(width);
142            }
143            command.append(";");
144            
145            return command.toString();
146        }
147
148        return "";
149    }
150
151    // Getters
152    public CommandType getCommandType() { return commandType; }
153    public String getFilePath() { return filePath; }
154    public String getDelimiter() { return delimiter; }
155    public String getQuote() { return quote; }
156    public String getEncoding() { return encoding; }
157    public boolean isIndicData() { return indicData; }
158    public Integer getWidth() { return width; }
159
160    // Setters
161    public void setFilePath(String filePath) { this.filePath = filePath; }
162    public void setDelimiter(String delimiter) { this.delimiter = delimiter; }
163    public void setQuote(String quote) { this.quote = quote; }
164    public void setEncoding(String encoding) { this.encoding = encoding; }
165    public void setIndicData(boolean indicData) { this.indicData = indicData; }
166    public void setWidth(Integer width) { this.width = width; }
167
168    public void accept(TParseTreeVisitor v){
169        v.preVisit(this);
170        v.postVisit(this);
171    }
172
173    public void acceptChildren(TParseTreeVisitor v){
174        v.preVisit(this);
175        v.postVisit(this);
176    }
177}