package com.algobase.share.network;

import android.webkit.WebSettings;
import android.os.Build;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.ArrayList;

import java.net.URL;
import java.net.HttpURLConnection;

import java.lang.StringBuilder;


public class HttpClient {

 String url_str;
 int connect_timeout = 10000; // 10 sec 
 int read_timeout = 60000; // 1 min

 long content_length = 0;

 //String user_agent = null;

 String user_agent =
        "Mozilla/5.0 (Linux; Android 9; SM-A102U) AppleWebKit/537.36 " +
        "(KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36";


 HttpURLConnection conn;
 int response_code;
 String response_msg;
 String redirect_url;
 String error_str;

 public void showProgress(int kb) {}

 public HttpClient(String s) { url_str = s; }
 public HttpClient(String s, int t) { url_str = s; connect_timeout = t; }

 public void setTimeout(int t)      { connect_timeout = t; }
 public void setReadTimeout(int t)  { read_timeout = t; }
 public void setUserAgent(String s) { user_agent = s; }

 public int    getResponseCode()    { return response_code; }
 public String getResponseMessage() { return response_msg; }
 public String getRedirectUrl()     { return redirect_url; }
 public long   getContentLength()   { return content_length; }
 public String getError()           { return error_str; }



 private void disconnect() {  
   if (conn == null) return;
   conn.disconnect(); 
   conn = null;
 }

 private boolean connect()
 {
   redirect_url = null;

   content_length = 0;

   try {
     URL url = new URL(url_str);

     conn = (HttpURLConnection)url.openConnection();

     conn.setConnectTimeout(connect_timeout);
     conn.setReadTimeout(read_timeout);

     if (user_agent != null) {
       conn.setRequestProperty("User-Agent",user_agent);
     }

     // default ?
     conn.setRequestProperty("Connection","Keep-Alive");

    // this seems to prevent osm blocking - why ?
/*
    conn.setRequestProperty("Accept-Language","en-US,en;q=0.9");
*/
    conn.setRequestProperty("Accept-Language",
                            "de, en-US;q=0.8, en;q=0.7, *;q=0.5");


//    conn.setRequestProperty("Accept",
//    "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
//     conn.setRequestProperty("Accept-Encoding","gzip, deflate");
//     conn.setRequestProperty("DNT","1");
//     conn.setRequestProperty("Upgrade-Insecure-Requests","1");


     conn.setRequestMethod("GET");
     conn.setDoInput(true);
     conn.setFollowRedirects(true);

/*
conn.setUseCaches(false);
conn.setRequestProperty("Accept-Charset","UTF-8");
*/

     conn.connect();

     response_code = conn.getResponseCode();
     response_msg = conn.getResponseMessage();

     content_length = conn.getContentLength();

   } catch(Exception e) { conn = null; 
                          error_str = "http_client: " + e.toString(); }

   if (conn == null) return false;


   if (response_code == HttpURLConnection.HTTP_MOVED_TEMP ||
       response_code == HttpURLConnection.HTTP_MOVED_PERM ||
       response_code == HttpURLConnection.HTTP_SEE_OTHER)
   { redirect_url = conn.getHeaderField("Location");
     error_str = "http_client: redirect";
     disconnect();
     return false;
    }


   //if (response_code != HttpURLConnection.HTTP_OK)
   if (response_code >= 400 && response_code <=499)
   { error_str = "Response Code: " + response_code;
     if (response_msg != null) 
       error_str += " (" + response_msg + ")";
     disconnect();
     return false;
    }

   return true;
 }




 public String getString() { return getString(0); }

 public String getString(int max_len)
 {
   if (!connect()) return null;

   StringBuilder builder = new StringBuilder();
   char[] buffer = new char[2048];

   try {
    InputStream in = conn.getInputStream();
    int n = 0;
    InputStreamReader reader = new InputStreamReader(in);
    while ((n = reader.read(buffer,0,buffer.length)) != -1) 
    { builder.append(buffer,0,n);
      if (max_len > 0 && builder.length() > max_len) break;
     }
    in.close();

   } catch(Exception e) { error_str = "http_client.getString: " + e.toString(); }

   disconnect();

   return (builder.length() == 0) ? null : builder.toString();
 }


 public String[] getLines()
 { 
   if (!connect()) return null;

   ArrayList<String> L = new ArrayList<String>();

   try {
     InputStream in = conn.getInputStream();
     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
     String line = null;
     while((line = reader.readLine()) != null) L.add(line);
     in.close();
   } catch(Exception e) { error_str = "http_client.getLines: " + e.toString(); }

   disconnect();

   int n = L.size();

   if (n == 0) return null;

   String[] lines  = new String[n];
   for(int i=0; i<n; i++) lines[i] = L.get(i);
   return lines;
 }


 public boolean getFile(File file)
 { 
   byte[] buffer = new byte[2048];

   boolean result = true;

   if (!connect()) return false;
 
   int count = 0;

   try {
     FileOutputStream fos = new FileOutputStream(file);
     InputStream in = conn.getInputStream();
 
     int n = 0;
     while ((n = in.read(buffer,0,buffer.length)) != -1) 
     { fos.write(buffer, 0, n);
       count += n;
       int kb = count/1024;
       showProgress(kb);
     }
     fos.close();
     in.close();
 
   } catch(IOException e) { error_str = "http_client: " + e.toString();
                            result = false;
                           }

   
   if (result)
   { //long c_len = conn.getContentLength();
/*
     if (count != content_length)
     { error_str = "http_client: uncomplete download: " + count + " / " + content_length + " bytes";
       result = false;
      }
*/
    }

   disconnect();
 
   return result;
 }

}

