/**
 * 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.service;

import static org.junit.jupiter.api.Assertions.*;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.test.util.ReflectionTestUtils;

import com.softcorporation.sandi.base.service.solr.SolrSynonymService;
import com.softcorporation.sandi.base.util.SynonymException;

public class SynonymServiceStemmingTest {

    @TempDir
    Path tempDir;
    
    private SolrSynonymService synonymService;
    
    @BeforeEach
    public void setUp() throws IOException {
        synonymService = new SolrSynonymService();
        
        ReflectionTestUtils.setField(synonymService, "sandiLanguages", "en");
        ReflectionTestUtils.setField(synonymService, "synonymsDirectory", tempDir.toString());
        ReflectionTestUtils.setField(synonymService, "stemmingEnabled", true);
        
        createTestSynonymFile();
        
        synonymService.init();
    }
    
    private void createTestSynonymFile() throws IOException {
        File synonymFile = tempDir.resolve("test_synonyms.txt").toFile();
        try (FileWriter writer = new FileWriter(synonymFile)) {
            writer.write("running => run, jog, sprint\n");
            writer.write("cars => car, automobile, vehicle\n");
            writer.write("books => book, novel, publication\n");
            writer.write("coding => code, programming, development\n");
        }
    }
    
    @Test
    public void testExactWordMatch() throws SynonymException {
        List<String> synonyms = synonymService.getAllSynonyms("running", "test_en");
        
        assertNotNull(synonyms);
        assertEquals(3, synonyms.size());
        assertTrue(synonyms.contains("run"));
        assertTrue(synonyms.contains("jog"));
        assertTrue(synonyms.contains("sprint"));
    }
    
    @Test
    public void testStemBasedMatch() throws SynonymException {
        List<String> synonyms = synonymService.getAllSynonyms("runs", "test_en");
        
        assertNotNull(synonyms);
        assertTrue(synonyms.size() > 0);
        assertTrue(synonyms.contains("run") || synonyms.contains("jog") || synonyms.contains("sprint"));
    }
    
    @Test
    public void testPluralFormMatch() throws SynonymException {
        List<String> synonyms = synonymService.getAllSynonyms("car", "test_en.txt");
        
        assertNotNull(synonyms);
        assertTrue(synonyms.size() > 0);
        assertTrue(synonyms.contains("car") || synonyms.contains("automobil") || synonyms.contains("vehicl"));
    }
    
    @Test
    public void testStemmingDisabled() throws SynonymException {
        ReflectionTestUtils.setField(synonymService, "stemmingEnabled", false);
        synonymService.init();
        
        List<String> synonyms = synonymService.getAllSynonyms("runs", "test_en");
        assertEquals(0, synonyms.size());
    }
}