/*
 * @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.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Set;
import net.ranides.assira.collection.query.CQuery;
import net.ranides.assira.io.IOStreams;
import net.ranides.assira.io.uri.URITime;
import net.ranides.assira.io.uri.URIFlags;
import net.ranides.assira.io.uri.URIHandle;
import net.ranides.assira.text.Charsets;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public abstract class CHandle implements URIHandle {
    
    private static final String NSE = "Not supported by URIHandler: ";

    @Override
    public String scheme() throws IOException {
        return uri().getScheme();
    }

    @Override
    public void close() throws IOException {
        // do nothing
    }
    
    @Override
    public File file() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public Path path() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public Charset charset() throws IOException {
        return Charsets.UTF8;
    }

    @Override
    public Set<URIFlags> flags() throws IOException {
        return URIFlags.collect();
    }

    @Override
    public boolean exists() throws IOException {
        return URIFlags.EXISTS.matches(this);
    }
    
    @Override
    public Instant time(URITime ut) throws IOException {
        throw new IOException(NSE + scheme() + " " + ut);
    }

    @Override
    public long size() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public URIHandle parent() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public CQuery<URIHandle> scan() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public InputStream istream() throws IOException {
        throw new IOException(NSE + scheme());
    }
    
    @Override
    public InputStream istream(long begin) throws IOException {
        return istream(begin, Long.MAX_VALUE);
    }
    
    @Override
    public InputStream istream(long begin, long end) throws IOException {
        return IOStreams.limit(istream(), begin, end);
    }

    @Override
    public OutputStream ostream() throws IOException {
        throw new IOException(NSE + scheme());
    }
    
    @Override
    public Reader reader(Charset cs) throws IOException {
        return new InputStreamReader(istream(), cs);
    }

    @Override
    public Reader reader() throws IOException {
        InputStream is = istream();
        Charset cs = charset();
        return new InputStreamReader(is, cs);
    }

    @Override
    public Writer writer(Charset cs) throws IOException {
        return new OutputStreamWriter(ostream(), cs);
    }
    
    @Override
    public Writer writer() throws IOException {
        OutputStream os = ostream();
        Charset cs = charset();
        return new OutputStreamWriter(os, cs);
    }

    @Override
    public void delete() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public void create() throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public void move(String target) throws IOException {
        try(URIHandle t = resolver().resolve(target)) {
            move(t);
        }
    }
    
    @Override
    public void move(URIHandle target) throws IOException {
        throw new IOException(NSE + scheme());
    }

    @Override
    public void copy(String target) throws IOException {
        try(URIHandle t = resolver().resolve(target)) {
            copy(t);
        }
    }
    
    @Override
    public void copy(URIHandle target) throws IOException {
        try(InputStream istream = istream()) {
            try(OutputStream ostream = target.ostream()) {
                IOStreams.copy(istream, ostream);
            }
        } 
    }
    
}
