/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.io.uri;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.ranides.assira.collection.maps.HashMultiMap;
import org.junit.Test;
import static net.ranides.assira.junit.NewAssert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class URIUtilsTest {
    
    @Test
    public void testEncodeURL() {
        assertEquals("hello%3Aworld%3Fparam%3D5", URIUtils.encodeURL("hello:world?param=5"));
        
        assertEquals("hello%3Aworld%3Fparam%3D5", URIUtils.encodeURL("hello:world?param=5", new FCharset("UTF-8")));
        
        assertThrows(AssertionError.class, ()->{
            URIUtils.encodeURL("hello:world?param=5", new FCharset("UFC888"));
        });
        
    }
    
    @Test
    public void testDecodeURL() {
        assertEquals("hello:world?param=5", URIUtils.decodeURL("hello%3Aworld%3Fparam%3D5"));
        
        assertEquals("hello:world?param=5", URIUtils.decodeURL("hello%3Aworld%3Fparam%3D5", new FCharset("UTF-8")));
        
        assertThrows(AssertionError.class, ()->{
            URIUtils.decodeURL("hello%3Aworld%3Fparam%3D5", new FCharset("UFC888"));
        });
    }
    
    @Test
    public void testGetQueryParams() throws URISyntaxException {
        URI u1 = new URI("file://root?charset=UTF-8&endl=unix&follow&fs=ntfs&a=1&a=2");
        URI u2 = new URI("file://root?charset=UTF-8");
        URI u3 = new URI("file://root?charset");
        URI u4 = new URI("file://root?");
        URI u5 = new URI("file://root");
        
        Map<String,String> exp1 = new HashMultiMap<>();
        exp1.put("endl", "unix");
        exp1.put("charset", "UTF-8");
        exp1.put("follow", "");
        exp1.put("fs", "ntfs");
        exp1.put("a", "2");
        exp1.put("a", "1");
        assertEquivalent(exp1, URIUtils.getParams(u1));
        
        Map<String,String> exp2 = new HashMap<>();
        exp2.put("charset", "UTF-8");
        assertEquivalent(exp2, URIUtils.getParams(u2));
        
        Map<String,String> exp3 = new HashMap<>();
        exp3.put("charset", "");
        assertEquivalent(exp3, URIUtils.getParams(u3));
        
        assertEquivalent(Collections.emptyMap(), URIUtils.getParams(u4));
        assertEquivalent(Collections.emptyMap(), URIUtils.getParams(u5));
    }
    
    private static final class FCharset extends Charset {

        public FCharset(String name) {
            super(name, new String[0]);
        }

        @Override
        public boolean contains(Charset cs) {
            throw new UnsupportedOperationException();
        }

        @Override
        public CharsetDecoder newDecoder() {
            throw new UnsupportedOperationException();
        }

        @Override
        public CharsetEncoder newEncoder() {
            throw new UnsupportedOperationException();
        }
        
    }
    
    @Test
    @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
    public void testGetFile() throws URISyntaxException {
        assertEquals(new File("/home/data/file"), URIUtils.getFile(new URI("file:/home/data/file")));
        assertEquals(new File("/home/data/file"), URIUtils.getFile(new URI("file://home/data/file")));
        assertEquals(new File("/home/data/file"), URIUtils.getFile(new URI("file:///home/data/file")));
         
        assertEquals(new File("/domain.net/path/to/file"), URIUtils.getFile(new URI("http:///domain.net/path/to/file")));
        assertEquals(new File("/domain.net/path/to/file"), URIUtils.getFile(new URI("http://domain.net/path/to/file")));
        assertEquals(new File("/domain.net/path/to/file"), URIUtils.getFile(new URI("http:/domain.net/path/to/file")));
        assertEquals(new File("domain.net/path/to/file"), URIUtils.getFile(new URI("http:domain.net/path/to/file")));
    }
	
}
