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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import net.ranides.assira.io.uri.URIFlags;
import static net.ranides.assira.io.uri.URIFlags.*;
import net.ranides.assira.io.uri.URIHandle;
import net.ranides.assira.io.uri.URIResolver;
import net.ranides.assira.io.uri.URITime;
import static net.ranides.assira.junit.NewAssert.*;
import net.ranides.assira.text.Charsets;
import net.ranides.assira.text.IOStrings;
import org.junit.Test;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class CHTTPHandlerTest {

    @Test
    public void testDynamicList() throws IOException, URISyntaxException {
        
        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/");
        URIHandle handle1 = resolve(uri);
        
        assertEquals(uri, handle1.uri());
        assertEquals(Charsets.UTF8, handle1.charset());
        assertEquals(true, handle1.exists());
        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT), handle1.flags());
        assertEquals("HTML PUBLIC \"-//W3C//DTD HTML 3", IOStrings.read(handle1.istream(10,40), handle1.charset()));
        
        URIHandle handle2 = resolve(uri);
        assertEquals(1231, IOStrings.read(handle2.reader()).length());
        assertEquals(Instant.now(), handle2.time(URITime.MODIFIED), Duration.ofMinutes(60));
        assertEquals(1231, handle2.size());
        
        URIHandle handle3 = resolve(uri);
        assertEquals(-1, handle3.size());

    }
    
    @Test
    public void testStaticText() throws IOException, URISyntaxException {
        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.pom");
        URIHandle handle1 = resolve(uri);

        assertEquals(uri, handle1.uri());
        assertEquals(Charsets.UTF8, handle1.charset());
        assertEquals(true, handle1.exists());
        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT, SIZE, SEEK), handle1.flags());
        assertEquals("mlns=\"", IOStrings.read(handle1.istream(10,15), handle1.charset()));
        assertThrows(IOException.class, ()->{
            IOStrings.read(handle1.reader());
        });
        
        URIHandle handle2 = resolve(uri);
        assertEquals(6964, IOStrings.read(handle2.reader()).length());
        assertEquals(Instant.parse("2013-03-08T01:58:31Z"), handle2.time(URITime.MODIFIED));
        assertThrows(IOException.class, ()->{
            handle2.time(URITime.ACCESSED);
        });
        assertEquals(6964, handle2.size());
    }
    
    @Test
    public void testNotFound() throws IOException, URISyntaxException {
        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.po");
        URIHandle handle = resolve(uri);
        
        assertEquals(uri, handle.uri());
        assertEquals(Charsets.UTF8, handle.charset());
        assertEquals(false, handle.exists());
        assertEquals(URIFlags.constant(FILE, TEXT, SIZE), handle.flags());
        assertEquals(Instant.now(), handle.time(URITime.MODIFIED), Duration.ofMinutes(60));
        
        assertThrows(IOException.class, ()->{
            handle.size();
        });
        
        assertThrows(FileNotFoundException.class, ()->{
            IOStrings.read(handle.istream(10,15), handle.charset());
        });
        
        assertThrows(FileNotFoundException.class, ()->{
            IOStrings.read(handle.reader());
        });
    }
    
    @Test
    public void testDynamicPage() throws IOException, URISyntaxException {
        URI uri = new URI("http://info.ranides.net/");
        URIHandle handle1 = resolve(uri);
        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT), handle1.flags());
        assertEquals("/DTD XHTML 1.0 Trans", IOStrings.read(handle1.istream(30, 50), Charsets.UTF8));
        assertEquals(-1, handle1.size());
        
        URIHandle handle2 = resolve(uri);
        assertTrue(IOStrings.read(handle2.reader()).contains("This program is free software;"));
        assertEquals(-1, handle2.size());
        
        assertTrue(IOStrings.read(resolve(uri).reader(Charsets.UTF8)).contains("This program is free software;"));
    }

    private static URIHandle resolve(URI uri) throws IOException {
        return new CHTTPHandler().resolve(uri);
    }
    
    @Test
    public void testBinary() throws IOException, URISyntaxException {   
        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1");
        URIHandle handle1 = resolve(uri);
        
        assertEquals(uri, handle1.uri());
        assertThrows(IOException.class, ()->{
            handle1.charset();
        });
        assertThrows(IOException.class, ()->{
            handle1.reader();
        });
        assertEquals(true, handle1.exists());
        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, BINARY, SIZE, SEEK), handle1.flags());
        assertEquals(Instant.parse("2013-03-08T01:58:30Z"), handle1.time(URITime.MODIFIED));
        assertEquals(40, handle1.size());
        
        URIHandle handle2 = resolve(uri);
        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df", IOStrings.read(handle2.istream(), Charsets.US_ASCII));
        
        URIHandle handle3 = resolve(uri);
        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df", IOStrings.read(handle3.reader(Charsets.US_ASCII)));
    }
    
    @Test
    public void testError() throws IOException, URISyntaxException { 
        URIHandle handle1 = resolve(new URI("http://m.maven.ranides.net/"));
        assertEquals(URIFlags.constant(FILE), handle1.flags());
        
        URIHandle handle2 = resolve(new URI("http://no.domain/"));
        assertEquals(URIFlags.constant(FILE), handle2.flags());
    }
    
    @Test
    public void testCopy() throws IOException, URISyntaxException {
        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1");
        URIHandle input = resolve(uri);
        File file = File.createTempFile("CHttpHandler", ".test");
        file.deleteOnExit();
        URIHandle target = new URIResolver(Arrays.asList(new CFileHandler())).resolve(file);
        
        input.copy(target);
        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df",IOStrings.read(file, Charsets.UTF8));
    }
    
    @Test
    public void testMove() throws IOException, URISyntaxException {
        URIHandle src = resolve(new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1"));
        URIHandle dst = resolve(new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1m"));
        assertThrows(IOException.class, ()->{
            src.move(dst);
        });
    }
    
}
