package com.skr.mdm.util;

import org.springframework.core.io.AbstractFileResolvingResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;

public class SelfUrlResourceUtil extends AbstractFileResolvingResource {
    @Nullable
	private final URI uri;
    private final URL url;
    private final URL cleanedUrl;

    public SelfUrlResourceUtil(URI uri) throws MalformedURLException {
        Assert.notNull(uri, "URI must not be null");
        this.uri = uri;
        this.url = uri.toURL();
        this.cleanedUrl = this.getCleanedUrl(this.url, uri.toString());
    }

    public SelfUrlResourceUtil(URL url) {
        Assert.notNull(url, "URL must not be null");
        this.url = url;
        this.cleanedUrl = this.getCleanedUrl(this.url, url.toString());
        this.uri = null;
    }



    public SelfUrlResourceUtil(String protocol, String location, @Nullable String fragment) throws MalformedURLException {
        try {
            this.uri = new URI(protocol, location, fragment);
            this.url = this.uri.toURL();
            this.cleanedUrl = this.getCleanedUrl(this.url, this.uri.toString());
        } catch (URISyntaxException var6) {
            MalformedURLException exToThrow = new MalformedURLException(var6.getMessage());
            exToThrow.initCause(var6);
            throw exToThrow;
        }
    }

    private URL getCleanedUrl(URL originalUrl, String originalPath) {
        String cleanedPath = StringUtils.cleanPath(originalPath);
        if (!cleanedPath.equals(originalPath)) {
            try {
                return new URL(cleanedPath);
            } catch (MalformedURLException var5) {
            }
        }

        return originalUrl;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        URLConnection con = this.url.openConnection();
        con.setConnectTimeout(5 * 60000);
        con.setReadTimeout(5 * 60000);
        ResourceUtils.useCachesIfNecessary(con);

        try {
            return con.getInputStream();
        } catch (IOException var3) {
            if (con instanceof HttpURLConnection) {
                ((HttpURLConnection)con).disconnect();
            }

            throw var3;
        }
    }

    @Override
    public URL getURL() {
        return this.url;
    }

	@Override
    public URI getURI() throws IOException {
        return this.uri != null ? this.uri : super.getURI();
    }
	@Override
    public boolean isFile() {
        return this.uri != null ? super.isFile(this.uri) : super.isFile();
    }

	@Override
    public File getFile() throws IOException {
        return this.uri != null ? super.getFile(this.uri) : super.getFile();
    }

	@Override
    public Resource createRelative(String relativePath) throws MalformedURLException {
        return new SelfUrlResourceUtil(this.createRelativeURL(relativePath));
    }

    protected URL createRelativeURL(String relativePath) throws MalformedURLException {
        if (relativePath.startsWith("/")) {
            relativePath = relativePath.substring(1);
        }

        relativePath = StringUtils.replace(relativePath, "#", "%23");
        return new URL(this.url, relativePath);
    }
    @Override
    public String getFilename() {
        return StringUtils.getFilename(this.cleanedUrl.getPath());
    }
    @Override
    public String getDescription() {
        return "URL [" + this.url + "]";
    }

    @Override
    public boolean equals(@Nullable Object other) {
        return this == other || other instanceof SelfUrlResourceUtil && this.cleanedUrl.equals(((SelfUrlResourceUtil)other).cleanedUrl);
    }
    @Override
    public int hashCode() {
        return this.cleanedUrl.hashCode();
    }
    @Override
    protected void customizeConnection(HttpURLConnection con) throws IOException {
//        con.setRequestMethod("HEAD");
    }
}