package com.nulabinc.backlog4j.http;

import com.nulabinc.backlog4j.BacklogAPIException;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * @author nulab-inc
 */
public class BacklogHttpResponseImpl implements BacklogHttpResponse {
    protected HttpURLConnection urlConnection;
    protected InputStream inputStream;
    protected int statusCode;
    protected String responseAsString = null;
    protected LocalDateTime rateLimitResetDate = null;
    protected String rateLimitReset = null;

    public BacklogHttpResponseImpl(HttpURLConnection urlConnection) {
        try {
            this.urlConnection = urlConnection;
            this.statusCode = urlConnection.getResponseCode();
            if (200 <= this.statusCode && this.statusCode <= 299) {
                this.inputStream = new BufferedInputStream(urlConnection.getInputStream());
            } else {
                this.inputStream = new BufferedInputStream(urlConnection.getErrorStream());
            }
            rateLimitReset = urlConnection.getHeaderField("X-RateLimit-Reset");
            setRateLimitResetDate(rateLimitReset);
        } catch (IOException e) {
            this.inputStream = new BufferedInputStream(urlConnection.getErrorStream());
        }
    }

    public String getRateLimitReset() {
        return rateLimitReset;
    }

    private void setRateLimitResetDate(String rateLimitReset) {
        if (StringUtils.isBlank(rateLimitReset)) {
            return;
        }
        try {
            rateLimitResetDate = LocalDateTime.ofInstant(Instant.ofEpochSecond(Long.parseLong(rateLimitReset)), ZoneId.systemDefault());
        } catch (Exception e) {
        }
    }

    public LocalDateTime getRateLimitResetDate() {
        return rateLimitResetDate;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public InputStream asInputStream() {
        return this.inputStream;
    }

    public String asString() {
        if (responseAsString == null && inputStream != null) {
            responseAsString = convertStreamToString();
        }
        return responseAsString;
    }

    private String convertStreamToString() {

        BufferedReader reader = null;
        StringBuilder sb = null;
        String line = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            sb = new StringBuilder();

            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

        } catch (UnsupportedEncodingException e) {
            throw new BacklogAPIException(e);
        } catch (IOException e) {
            throw new BacklogAPIException(e);
        } finally {
            try {
                inputStream.close();
                reader.close();
            } catch (IOException e) {
                throw new BacklogAPIException(e);
            }
        }
        return sb.toString();
    }

    public String getFileNameFromContentDisposition() {
        String disposition = this.urlConnection.getHeaderField("Content-Disposition");
        if (disposition != null) {
            String encode = disposition.substring(disposition.indexOf("=")+1,disposition.indexOf("''"));
            String fileName = disposition.substring(disposition.indexOf("''")+2);
            if(encode != null){
                try {
                    return URLDecoder.decode(fileName, encode);
                } catch (UnsupportedEncodingException e) {
                    throw new BacklogAPIException(e);
                }
            }else{
                return fileName;
            }
        }

        return null;
    }
}

@@ -869,34 +869,8 @@
 if (
-200 %3C= this.statusCode && 
 this
@@ -886,13 +886,12 @@
 de %3C
-= 299
+ 400
 ) %7B%0A

Use getErrorStream when http response status is over 400