package postgres.gen;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.stream.Collectors;

import lama.Query;
import lama.QueryAdapter;
import lama.Randomly;
import postgres.PostgresSchema.PostgresTable;

public class PostgresVacuumGenerator {

	public static Query create(PostgresTable table) {
		StringBuilder sb = new StringBuilder("VACUUM ");
		if (Randomly.getBoolean()) {
			// VACUUM [ ( { FULL | FREEZE | VERBOSE | ANALYZE | DISABLE_PAGE_SKIPPING } [,
			// ...] ) ] [ table_name [ (column_name [, ...] ) ] ]
			sb.append("(");
			for (int i = 0; i < Randomly.smallNumber() + 1; i++) {
				String option = Randomly.fromOptions("FULL", "FREEZE", "VERBOSE", "ANALYZE", "DISABLE_PAGE_SKIPPING");
				if (i != 0) {
					sb.append(", ");
				}
				sb.append(option);
			}
			sb.append(")");
			if (Randomly.getBoolean()) {
				addTableAndColumns(table, sb);
			}
		} else {
			String firstOption = Randomly.fromOptions("FULL", "FREEZE", "VERBOSE");
			sb.append(firstOption);
			if (Randomly.getBoolean()) {
				sb.append(" ANALYZE");
				addTableAndColumns(table, sb);
			} else {
				if (Randomly.getBoolean()) {
					sb.append(" ");
					sb.append(table.getName());
				}
			}
		}
		return new QueryAdapter(sb.toString()) {
			@Override
			public void execute(Connection con) throws SQLException {
				try {
					super.execute(con);
				} catch (SQLException e) {
					if (e.getMessage().contains("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")) {

					} else if (e.getMessage()
							.contains("ERROR: ANALYZE option must be specified when a column list is provided")) {

					} else if (e.getMessage().contains("deadlock")) {
						/*
						 * "FULL" commented out due to
						 * https://www.postgresql.org/message-id/CA%2Bu7OA6pL%
						 * 2B7Xm_NXHLenxffe3tCr3gTamVdr7zPjcWqW0RFM-A%40mail.gmail.com
						 */
					} else if (e.getMessage().contains("VACUUM cannot run inside a transaction block")) {
						
					} else {
						throw e;
					}
				}
			}
		};
	}

	private static void addTableAndColumns(PostgresTable table, StringBuilder sb) {
		sb.append(" ");
		sb.append(table.getName());
		if (Randomly.getBoolean()) {
			sb.append("(");
			sb.append(table.getRandomNonEmptyColumnSubset().stream().map(c -> c.getName())
					.collect(Collectors.joining(", ")));
			sb.append(")");
		}
	}

}

@@ -70,24 +70,77 @@
 LException;%0A
+import java.util.ArrayList;%0Aimport java.util.Arrays;%0A
 import java.
@@ -231,16 +231,50 @@
 ndomly;%0A
+import postgres.PostgresProvider;%0A
 import p
@@ -709,179 +709,541 @@
 %09%09%09%09
+ArrayList%3C
 String
+%3E
  opt
-ion = Randomly.fromOptions(%22FULL%22, %22FREEZE%22, %22VERBOSE%22, %22ANALYZE%22, %22DISABLE_PAGE_SKIPPING%22);%0A%09%09%09%09if (i != 0) %7B%0A%09%09%09%09%09sb.append(%22, %22);%0A%09%09%09%09%7D%0A%09%09%09%09sb.append(option);
+s = new ArrayList%3CString%3E(%0A%09%09%09%09%09%09Arrays.asList(%22FULL%22, %22FREEZE%22, %22ANALYZE%22, %22VERBOSE%22, %22DISABLE_PAGE_SKIPPING%22));%0A%09%09%09%09if (PostgresProvider.IS_POSTGRES_TWELVE) %7B%0A%09%09%09%09%09opts.add(%22SKIP_LOCKED%22);%0A%09%09%09%09%09opts.add(%22INDEX_CLEANUP%22);%0A%09%09%09%09%09opts.add(%22TRUNCATE%22);%0A%09%09%09%09%7D%0A%09%09%09%09String option = Randomly.fromList(opts);%0A%09%09%09%09if (i != 0) %7B%0A%09%09%09%09%09sb.append(%22, %22);%0A%09%09%09%09%7D%0A%09%09%09%09sb.append(option);%0A%09%09%09%09if (PostgresProvider.IS_POSTGRES_TWELVE && Randomly.getBoolean()) %7B%0A%09%09%09%09%09sb.append(%22 %22);%0A%09%09%09%09%09sb.append(Randomly.fromOptions(1, 0));%0A%09%09%09%09%7D
 %0A%09%09%09
@@ -2398,22 +2398,16 @@
 ck%22)) %7B%0A
-%09%09%09%09%09%09
 %0A%09%09%09%09%09%7D 

Extend VACUUM