/**
 * Copyright (c) 2025 SoftCorporation LLC. All rights reserved.
 *
 * The Software License, Version 1.0
 *
 * SoftCorporation LLC. grants you ("Licensee") a non-exclusive, royalty free,
 * license to use, modify and redistribute this software in source and binary
 * code form, provided that the following conditions are met:
 *
 * 1. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        SoftCorporation LLC. (http://www.softcorporation.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 2. This software and SoftCorporation name must not be used to
 *    promote products derived from the software without prior
 *    written permission. For written permission, please contact
 *    info@softcorporation.com.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 * IN NO EVENT SHALL THE SOFTCORPORATION BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
 *
 */
package com.softcorporation.sandi.base.util;

import java.util.Arrays;
import java.util.List;

import org.apache.solr.common.SolrDocument;
import org.json.JSONObject;

import com.softcorporation.sandi.base.model.Client;

/**
 * Factory class for creating test data objects
 */
public class TestDataFactory {

    private TestDataFactory() {
        // Utility class
    }

    /**
     * Create a basic test client with default values
     */
    public static Client createTestClient() {
        return createTestClient("test-client", "Test Client", "test-collection", true, false);
    }

    /**
     * Create a test client with specified parameters
     */
    public static Client createTestClient(String clientId, String name, String collection, boolean active, boolean legacy) {
        Client client = new Client();
        client.setClientId(clientId);
        client.setName(name);
        client.setCollection(collection);
        client.setActive(active);
        client.setLegacy(legacy);
        client.setFieldsHigh("title");
        client.setFieldsLow("tags,keywords,category");
        client.setFieldsContent("abstract,content");
        return client;
    }

    /**
     * Create a test client with custom fields
     */
    public static Client createTestClientWithFields(String clientId, String highFields, String lowFields, String contentFields) {
        Client client = createTestClient(clientId, "Test Client", "test-collection", true, false);
        client.setFieldsHigh(highFields);
        client.setFieldsLow(lowFields);
        client.setFieldsContent(contentFields);
        return client;
    }

    /**
     * Create a legacy test client
     */
    public static Client createLegacyTestClient() {
        return createTestClient("legacy-client", "Legacy Test Client", "legacy-collection", true, true);
    }

    /**
     * Create an inactive test client
     */
    public static Client createInactiveTestClient() {
        return createTestClient("inactive-client", "Inactive Test Client", "inactive-collection", false, false);
    }

    /**
     * Create a SolrDocument representing a client
     */
    public static SolrDocument createClientSolrDocument(String clientId, String name, String collection, boolean active, boolean legacy) {
        SolrDocument doc = new SolrDocument();
        doc.setField(Constants.FIELD_CLIENT_ID, clientId);
        doc.setField(Constants.FIELD_NAME, name);
        doc.setField(Constants.FIELD_COLLECTION, collection);
        doc.setField(Constants.FIELD_ACTIVE, active);
        doc.setField(Constants.FIELD_LEGACY, legacy);
        doc.setField(Constants.FIELDS_HIGH, "title");
        doc.setField(Constants.FIELDS_LOW, "tags,summary");
        doc.setField(Constants.FIELDS_CONTENT, "content");
        return doc;
    }

    /**
     * Create a SolrDocument representing a document
     */
    public static SolrDocument createDocumentSolrDocument(String id, String title, String content, String clientId) {
        SolrDocument doc = new SolrDocument();
        doc.setField("id", id);
        doc.setField("title", title);
        doc.setField("content", content);
        doc.setField(Constants.CLIENT_ID, clientId);
        doc.setField(Constants.TIMESTAMP, System.currentTimeMillis());
        return doc;
    }

    /**
     * Create a JSONObject representing a document
     */
    public static JSONObject createTestDocument(String id, String title, String content) {
        JSONObject doc = new JSONObject();
        doc.put("id", id);
        doc.put("title", title);
        doc.put("content", content);
        doc.put("author", "Test Author");
        doc.put("category", "test");
        doc.put("tags", Arrays.asList("tag1", "tag2"));
        doc.put("timestamp", System.currentTimeMillis());
        return doc;
    }

    /**
     * Create a JSONObject with specific fields for testing
     */
    public static JSONObject createTestDocument(String id) {
        JSONObject doc = new JSONObject();
        doc.put("id", id);
        doc.put("title", "Test Title for " + id);
        doc.put("content", "Test content for document " + id);
        doc.put("summary", "Test summary for " + id);
        doc.put("abstract", "Test abstract for " + id);
        doc.put("tags", "test,document,sample");
        doc.put("keywords", "keyword1,keyword2");
        doc.put("category", "technology");
        return doc;
    }

    /**
     * Create multiple test clients
     */
    public static List<Client> createMultipleTestClients(int count) {
        return Arrays.asList(
            createTestClient("client-1", "Client One", "collection-1", true, false),
            createTestClient("client-2", "Client Two", "collection-2", true, false),
            createTestClient("client-3", "Client Three", "collection-3", false, false),
            createTestClient("client-4", "Client Four", "collection-4", true, true)
        ).subList(0, Math.min(count, 4));
    }

    /**
     * Create test document with metadata
     */
    public static JSONObject createDocumentWithMetadata(String id, String title, String content) {
        JSONObject doc = createTestDocument(id, title, content);
        doc.put("author", "Test Author");
        doc.put("created_date", "2025-01-01T00:00:00Z");
        doc.put("modified_date", "2025-01-02T12:00:00Z");
        doc.put("language", "en");
        doc.put("format", "text/html");
        doc.put("size", content.length());
        doc.put("url", "http://example.com/documents/" + id);
        return doc;
    }

    /**
     * Create test document with arrays
     */
    public static JSONObject createDocumentWithArrays(String id) {
        JSONObject doc = new JSONObject();
        doc.put("id", id);
        doc.put("title", "Document with Arrays");
        doc.put("content", "This document has array fields");
        doc.put("authors", Arrays.asList("Author 1", "Author 2", "Author 3"));
        doc.put("tags", Arrays.asList("tag1", "tag2", "tag3", "tag4"));
        doc.put("categories", Arrays.asList("science", "technology"));
        doc.put("keywords", Arrays.asList("test", "array", "document", "sample"));
        return doc;
    }

    /**
     * Create search test data
     */
    public static class SearchTestData {
        private final String clientId;
        private final String collection;
        private final List<JSONObject> documents;

        public SearchTestData(String clientId, String collection, List<JSONObject> documents) {
            this.clientId = clientId;
            this.collection = collection;
            this.documents = documents;
        }

        public String getClientId() { return clientId; }
        public String getCollection() { return collection; }
        public List<JSONObject> getDocuments() { return documents; }
    }

    /**
     * Create comprehensive search test data
     */
    public static SearchTestData createSearchTestData() {
        String clientId = "search-test-client";
        String collection = "search-test-collection";
        
        List<JSONObject> documents = Arrays.asList(
            createDocumentForSearch("doc1", "Java Programming Guide", "Complete guide to Java programming", "technology", "programming"),
            createDocumentForSearch("doc2", "Python Tutorial", "Learn Python programming", "technology", "programming"),
            createDocumentForSearch("doc3", "Database Design", "Principles of database design", "technology", "database"),
            createDocumentForSearch("doc4", "Machine Learning Basics", "Introduction to machine learning", "science", "ai"),
            createDocumentForSearch("doc5", "Web Development", "Modern web development practices", "technology", "web")
        );

        return new SearchTestData(clientId, collection, documents);
    }

    private static JSONObject createDocumentForSearch(String id, String title, String content, String category, String topic) {
        JSONObject doc = new JSONObject();
        doc.put("id", id);
        doc.put("title", title);
        doc.put("content", content);
        doc.put("category", category);
        doc.put("topic", topic);
        doc.put("author", "Test Author");
        doc.put("created", "2025-01-01T00:00:00Z");
        doc.put("score", Math.random() * 10);
        return doc;
    }

    /**
     * Create test data for indexing tests
     */
    public static class IndexingTestData {
        private final String jobId;
        private final String clientId;
        private final String location;
        private final List<String> fileExtensions;

        public IndexingTestData(String jobId, String clientId, String location, List<String> fileExtensions) {
            this.jobId = jobId;
            this.clientId = clientId;
            this.location = location;
            this.fileExtensions = fileExtensions;
        }

        public String getJobId() { return jobId; }
        public String getClientId() { return clientId; }
        public String getLocation() { return location; }
        public List<String> getFileExtensions() { return fileExtensions; }
    }

    /**
     * Create indexing test data
     */
    public static IndexingTestData createIndexingTestData(String location) {
        return new IndexingTestData(
            "test-job-" + System.currentTimeMillis(),
            "indexing-test-client",
            location,
            Arrays.asList(".txt", ".html", ".pdf", ".doc")
        );
    }
}