import { pgTable, index, text, timestamp, integer, jsonb, foreignKey, real, uniqueIndex, primaryKey, boolean } from "drizzle-orm/pg-core"
import { sql } from "drizzle-orm"



export const applications = pgTable("applications", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	name: text(),
	description: text(),
	status: integer(),
	securityConfig: jsonb("security_config"),
	useCase: text("use_case"),
	providerConfig: jsonb("provider_config").notNull(),
	projectId: text("project_id"),
	testRuns: integer("test_runs"),
	providerType: text("provider_type"),
}, (table) => [
	index("applications_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
]);

export const configs = pgTable("configs", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
	name: text().notNull(),
	type: text().notNull(),
	config: jsonb().notNull(),
}, (table) => [
	index("configs_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
	index("configs_type_idx").using("btree", table.type.asc().nullsLast().op("text_ops")),
]);

export const defaultProviders = pgTable("default_providers", {
	id: text().primaryKey().notNull(),
	label: text().notNull(),
	group: text().notNull(),
	config: jsonb().notNull(),
}, (table) => [
	index("default_providers_group_idx").using("btree", table.group.asc().nullsLast().op("text_ops")),
	index("default_providers_label_idx").using("btree", table.label.asc().nullsLast().op("text_ops")),
]);

export const datasets = pgTable("datasets", {
	id: text().primaryKey().notNull(),
	tests: jsonb(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
});

export const evals = pgTable("evals", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	author: text(),
	description: text(),
	results: jsonb().notNull(),
	config: jsonb().notNull(),
	prompts: jsonb(),
	projectId: text("project_id"),
	vars: jsonb(),
	applicationId: text("application_id"),
}, (table) => [
	index("evals_author_idx").using("btree", table.author.asc().nullsLast().op("text_ops")),
	index("evals_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
	foreignKey({
			columns: [table.applicationId],
			foreignColumns: [applications.id],
			name: "evals_application_id_applications_id_fk"
		}),
]);

export const assertions = pgTable("assertions", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	name: text().notNull(),
	description: text(),
	group: text(),
	valueType: text("value_type"),
	mandatory: integer().default(0),
	additionalFields: jsonb("additional_fields"),
	label: text(),
	options: jsonb(),
	helpText: text("help_text"),
	placeholder: text(),
	providerResponseRequirements: jsonb("provider_response_requirements"),
}, (table) => [
	index("assertions_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
	index("assertions_group_idx").using("btree", table.group.asc().nullsLast().op("text_ops")),
	index("assertions_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
]);

export const pluginsPresets = pgTable("plugins_presets", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	description: text(),
	plugins: jsonb(),
}, (table) => [
	index("plugins_presets_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
]);

export const prompts = pgTable("prompts", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	prompt: text().notNull(),
	projectId: text("project_id").notNull(),
	tests: jsonb(),
	dataset: jsonb(),
	type: text(),
	userIntentions: jsonb("user_intentions"),
	userProfiles: jsonb("user_profiles"),
	openingMessage: text("opening_message"),
	minimumTurns: integer("minimum_turns"),
	maximumTurns: integer("maximum_turns"),
	chatStopCriteria: text("chat_stop_criteria"),
}, (table) => [
	index("prompts_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
]);

export const promptsLibrary = pgTable("prompts_library", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	name: text(),
	status: integer(),
	globalMetrics: jsonb("global_metrics").array(),
	projectId: text("project_id").notNull(),
}, (table) => [
	index("prompts_library_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
]);

export const providerSupportedLanguages = pgTable("provider_supported_languages", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	code: text().notNull(),
	speechSynthesisLanguage: text("SpeechSynthesisLanguage").notNull(),
	speechSynthesisVoiceName: text("SpeechSynthesisVoiceName").notNull(),
}, (table) => [
	index("provider_supported_languages_code_idx").using("btree", table.code.asc().nullsLast().op("text_ops")),
	index("provider_supported_languages_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
]);

export const securityConfig = pgTable("security_config", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	status: integer().notNull(),
	config: jsonb().notNull(),
	projectId: text("project_id"),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
}, (table) => [
	index("security_config_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
	index("security_config_project_id_idx").using("btree", table.projectId.asc().nullsLast().op("text_ops")),
	index("security_config_status_idx").using("btree", table.status.asc().nullsLast().op("int4_ops")),
]);

export const strategyPresets = pgTable("strategy_presets", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	description: text(),
	strategies: jsonb(),
	options: jsonb(),
}, (table) => [
	index("strategy_presets_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
]);

export const evalResults = pgTable("eval_results", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	evalId: text("eval_id").notNull(),
	promptIdx: integer("prompt_idx").notNull(),
	testIdx: integer("test_idx").notNull(),
	testCase: jsonb("test_case").notNull(),
	prompt: jsonb().notNull(),
	promptId: text("prompt_id"),
	applicationId: text("application_id"),
	provider: jsonb().notNull(),
	latencyMs: integer("latency_ms"),
	cost: real(),
	response: jsonb(),
	error: text(),
	failureReason: integer("failure_reason").default(0).notNull(),
	success: integer().notNull(),
	score: real().notNull(),
	gradingResult: jsonb("grading_result"),
	namedScores: jsonb("named_scores"),
	metadata: jsonb(),
	isRedteam: integer("is_redteam").default(0),
	traceId: text("trace_id"),
	projectId: text("project_id"),
}, (table) => [
	index("eval_result_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	index("eval_result_test_idx").using("btree", table.testIdx.asc().nullsLast().op("int4_ops")),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "eval_results_eval_id_evals_id_fk"
		}),
	foreignKey({
			columns: [table.promptId],
			foreignColumns: [prompts.id],
			name: "eval_results_prompt_id_prompts_id_fk"
		}),
	foreignKey({
			columns: [table.applicationId],
			foreignColumns: [applications.id],
			name: "eval_results_application_id_applications_id_fk"
		}),
]);

export const trusysDatasets = pgTable("trusys_datasets", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	type: text(),
	projectId: text("project_id").notNull(),
	data: jsonb(),
	count: integer().default(0),
	fields: jsonb(),
	config: jsonb(),
	status: integer().default(0).notNull(),
	createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
	updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
}, (table) => [
	index("trusys_datasets_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamp_ops")),
	index("trusys_datasets_project_id_idx").using("btree", table.projectId.asc().nullsLast().op("text_ops")),
]);

export const tags = pgTable("tags", {
	id: text().primaryKey().notNull(),
	name: text().notNull(),
	value: text().notNull(),
}, (table) => [
	index("tags_name_idx").using("btree", table.name.asc().nullsLast().op("text_ops")),
	uniqueIndex("tags_name_value_unique").using("btree", table.name.asc().nullsLast().op("text_ops"), table.value.asc().nullsLast().op("text_ops")),
]);

export const promptsLibraryPrompts = pgTable("prompts_library_prompts", {
	libraryId: text("library_id").notNull(),
	promptId: text("prompt_id").notNull(),
}, (table) => [
	foreignKey({
			columns: [table.libraryId],
			foreignColumns: [promptsLibrary.id],
			name: "prompts_library_prompts_library_id_prompts_library_id_fk"
		}),
	foreignKey({
			columns: [table.promptId],
			foreignColumns: [prompts.id],
			name: "prompts_library_prompts_prompt_id_prompts_id_fk"
		}),
]);

export const monitoringAlerts = pgTable("monitoring_alerts", {
	id: text().primaryKey().notNull(),
	applicationId: text("application_id").notNull(),
	alerts: jsonb(),
	emails: text(),
	webhook: text(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	projectId: text("project_id").notNull(),
	status: text().default('inactive').notNull(),
	alertsTriggered: integer("alerts_triggered").default(0),
}, (table) => [
	index("monitoring_alerts_application_id_idx").using("btree", table.applicationId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.applicationId],
			foreignColumns: [applications.id],
			name: "monitoring_alerts_application_id_applications_id_fk"
		}),
]);

export const testRuns = pgTable("test_runs", {
	id: text().primaryKey().notNull(),
	type: text().default('eval'),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	status: text().default('pending').notNull(),
	projectId: text("project_id"),
	applicationIds: jsonb("application_ids").notNull(),
	libraryId: text("library_id"),
	totalTestCase: integer("total_test_case"),
}, (table) => [
	index("test_runs_created_at_idx").using("btree", table.createdAt.asc().nullsLast().op("timestamptz_ops")),
	index("test_runs_status_idx").using("btree", table.status.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.libraryId],
			foreignColumns: [promptsLibrary.id],
			name: "test_runs_library_id_prompts_library_id_fk"
		}),
]);

export const monitoring = pgTable("monitoring", {
	id: text().primaryKey().notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	updatedAt: timestamp("updated_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
	applicationId: text("application_id").notNull(),
	logLocation: text("log_location").notNull(),
	serviceProvider: text("service_provider").notNull(),
	locationUrl: text("location_url").notNull(),
	samplingFrequency: text("sampling_frequency").notNull(),
	samplingPercentage: integer("sampling_percentage").notNull(),
	samplingCount: integer("sampling_count").notNull(),
	evaluationWindow: integer("evaluation_window").notNull(),
	metrics: jsonb().notNull(),
	secretName: text("secret_name").notNull(),
	pluginsByCategory: jsonb(),
}, (table) => [
	index("monitoring_application_id_idx").using("btree", table.applicationId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.applicationId],
			foreignColumns: [applications.id],
			name: "monitoring_application_id_applications_id_fk"
		}),
]);

export const evalsToDatasets = pgTable("evals_to_datasets", {
	evalId: text("eval_id").notNull(),
	datasetId: text("dataset_id").notNull(),
}, (table) => [
	index("evals_to_datasets_dataset_id_idx").using("btree", table.datasetId.asc().nullsLast().op("text_ops")),
	index("evals_to_datasets_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "evals_to_datasets_eval_id_evals_id_fk"
		}),
	foreignKey({
			columns: [table.datasetId],
			foreignColumns: [datasets.id],
			name: "evals_to_datasets_dataset_id_datasets_id_fk"
		}),
	primaryKey({ columns: [table.evalId, table.datasetId], name: "evals_to_datasets_eval_id_dataset_id_pk"}),
]);

export const evalsToPrompts = pgTable("evals_to_prompts", {
	evalId: text("eval_id").notNull(),
	promptId: text("prompt_id").notNull(),
}, (table) => [
	index("evals_to_prompts_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	index("evals_to_prompts_prompt_id_idx").using("btree", table.promptId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "evals_to_prompts_eval_id_evals_id_fk"
		}).onDelete("cascade"),
	foreignKey({
			columns: [table.promptId],
			foreignColumns: [prompts.id],
			name: "evals_to_prompts_prompt_id_prompts_id_fk"
		}),
	primaryKey({ columns: [table.evalId, table.promptId], name: "evals_to_prompts_eval_id_prompt_id_pk"}),
]);

export const evalsToTags = pgTable("evals_to_tags", {
	evalId: text("eval_id").notNull(),
	tagId: text("tag_id").notNull(),
}, (table) => [
	index("evals_to_tags_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	index("evals_to_tags_tag_id_idx").using("btree", table.tagId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "evals_to_tags_eval_id_evals_id_fk"
		}),
	foreignKey({
			columns: [table.tagId],
			foreignColumns: [tags.id],
			name: "evals_to_tags_tag_id_tags_id_fk"
		}),
	primaryKey({ columns: [table.evalId, table.tagId], name: "evals_to_tags_eval_id_tag_id_pk"}),
]);

export const testRunsToDatasets = pgTable("test_runs_to_datasets", {
	testRunId: text("test_run_id").notNull(),
	datasetId: text("dataset_id").notNull(),
}, (table) => [
	index("test_runs_to_datasets_dataset_id_idx").using("btree", table.datasetId.asc().nullsLast().op("text_ops")),
	index("test_runs_to_datasets_test_run_id_idx").using("btree", table.testRunId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.testRunId],
			foreignColumns: [testRuns.id],
			name: "test_runs_to_datasets_test_run_id_test_runs_id_fk"
		}).onDelete("cascade"),
	foreignKey({
			columns: [table.datasetId],
			foreignColumns: [trusysDatasets.id],
			name: "test_runs_to_datasets_dataset_id_trusys_datasets_id_fk"
		}),
	primaryKey({ columns: [table.testRunId, table.datasetId], name: "test_runs_to_datasets_test_run_id_dataset_id_pk"}),
]);

export const testRunsToSecurityConfigs = pgTable("test_runs_to_security_configs", {
	testRunId: text("test_run_id").notNull(),
	securityConfigId: text("security_config_id").notNull(),
	config: jsonb("config"),
}, (table) => [
	index("test_runs_to_security_configs_security_config_id_idx").using("btree", table.securityConfigId.asc().nullsLast().op("text_ops")),
	index("test_runs_to_security_configs_test_run_id_idx").using("btree", table.testRunId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.testRunId],
			foreignColumns: [testRuns.id],
			name: "test_runs_to_security_configs_test_run_id_test_runs_id_fk"
		}).onDelete("cascade"),
	foreignKey({
			columns: [table.securityConfigId],
			foreignColumns: [securityConfig.id],
			name: "test_runs_to_security_configs_security_config_id_security_confi"
		}),
	primaryKey({ columns: [table.testRunId, table.securityConfigId], name: "test_runs_to_security_configs_test_run_id_security_config_id_pk"}),
]);

export const testRunsToEvals = pgTable("test_runs_to_evals", {
	testRunId: text("test_run_id").notNull(),
	evalId: text("eval_id").notNull(),
}, (table) => [
	index("test_runs_to_evals_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	index("test_runs_to_evals_test_run_id_idx").using("btree", table.testRunId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.testRunId],
			foreignColumns: [testRuns.id],
			name: "test_runs_to_evals_test_run_id_test_runs_id_fk"
		}).onDelete("cascade"),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "test_runs_to_evals_eval_id_evals_id_fk"
		}),
	primaryKey({ columns: [table.testRunId, table.evalId], name: "test_runs_to_evals_test_run_id_eval_id_pk"}),
]);

export const evalsToTraces = pgTable("evals_to_traces", {
	evalId: text("eval_id").notNull(),
	traceId: text("trace_id").notNull(),
	projectId: text("project_id").notNull(),
	createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).default(sql`CURRENT_TIMESTAMP`).notNull(),
}, (table) => [
	index("evals_to_traces_eval_id_idx").using("btree", table.evalId.asc().nullsLast().op("text_ops")),
	index("evals_to_traces_project_id_idx").using("btree", table.projectId.asc().nullsLast().op("text_ops")),
	index("evals_to_traces_trace_id_idx").using("btree", table.traceId.asc().nullsLast().op("text_ops")),
	foreignKey({
			columns: [table.evalId],
			foreignColumns: [evals.id],
			name: "evals_to_traces_eval_id_evals_id_fk"
		}),
	primaryKey({ columns: [table.evalId, table.traceId], name: "evals_to_traces_eval_id_trace_id_pk"}),
]);
