package info.metadude.java.library.overpass.utils;

import java.util.Map;

/**
 * Constructs a data query for Overpass-Turbo
 * Example: "[out:json];node(around:600,52.516667,13.383333)[\"amenity\"=\"post_box\"];out qt 13;"
 */
public class DataQuery {

    protected final int radius;

    protected final double longitude;

    protected final double latitude;

    protected final Map<String, String> tags;

    protected final boolean sortByDistance;

    protected final int maxResponseCount;

    public DataQuery(int radius,
                     double longitude,
                     double latitude,
                     Map<String, String> tags,
                     boolean sortByDistance,
                     int maxResponseCount) {
        this.radius = radius;
        this.longitude = longitude;
        this.latitude = latitude;
        this.tags = tags;
        this.sortByDistance = sortByDistance;
        this.maxResponseCount = maxResponseCount;
        validateParams();
    }

    public String getFormattedDataQuery() {
        String sortInstruction = sortByDistance ? "qt " : "";
        String formattedTags = getFormattedTags();
        return "[out:json];" +
                "node(around:" + radius + "," + longitude + "," + latitude + ")" +
                formattedTags +
                "out " +
                sortInstruction +
                maxResponseCount + ";";
    }

    private void validateParams() {
        if (radius < 2) {
            throw new IllegalArgumentException("Expected maximum radius to be greater then one, but was " + radius);
        }
        if (longitude < -180 || longitude > 180) {
            throw new IllegalArgumentException("Expected longitude between -180 and 180, but was " + longitude);
        }
        if (latitude < -90 || latitude > 90) {
            throw new IllegalArgumentException("Expected latitude between -90 and 90, but was " + latitude);
        }
        if (tags == null || tags.isEmpty()) {
            throw new IllegalArgumentException("Expected at least one tag.");
        }
        if (maxResponseCount < 1) {
            throw new IllegalArgumentException("Expected maximum response count to be " +
                    "greater then zero, but was " + maxResponseCount);
        }
    }

    private String getFormattedTags() {
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : tags.keySet()) {
            stringBuilder
                    .append("[\"")
                    .append(key).append("\"=\"")
                    .append(tags.get(key))
                    .append("\"]");
        }
        stringBuilder.append(";");
        return stringBuilder.toString();
    }

}

@@ -308,25 +308,37 @@
 double l
-ong
+at
 itude;
+ // 52.516667
 %0A%0A    pr
@@ -359,24 +359,38 @@
 double l
-at
+ong
 itude;
+ // 13.383333
 %0A%0A    pr
@@ -551,16 +551,54 @@
 radius,%0A
+                     double latitude,%0A
         
@@ -632,46 +632,8 @@
 de,%0A
-                     double latitude,%0A
     
@@ -809,19 +809,18 @@
   this.l
-ong
+at
 itude = 
@@ -820,19 +820,18 @@
 tude = l
-ong
+at
 itude;%0A 
@@ -835,34 +835,35 @@
 ;%0A        this.l
-at
+ong
 itude = latitude
@@ -847,34 +847,35 @@
 is.longitude = l
-at
+ong
 itude;%0A        t
@@ -1253,27 +1253,26 @@
 us + %22,%22 + l
-ong
+at
 itude + %22,%22 
@@ -1266,34 +1266,35 @@
 titude + %22,%22 + l
-at
+ong
 itude + %22)%22 +%0A  
@@ -1631,19 +1631,18 @@
    if (l
-ong
+at
 itude %3C 
@@ -1646,27 +1646,25 @@
  %3C -
-18
+9
 0 %7C%7C l
-ong
+at
 itude %3E 
 180)
@@ -1659,18 +1659,17 @@
 itude %3E 
-18
+9
 0) %7B%0A   
@@ -1723,19 +1723,18 @@
 pected l
-ong
+at
 itude be
@@ -1744,18 +1744,16 @@
 en -
-18
+9
 0 and 
-18
+9
 0, b
@@ -1760,27 +1760,26 @@
 ut was %22 + l
-ong
+at
 itude);%0A    
@@ -1789,34 +1789,35 @@
  %7D%0A        if (l
-at
+ong
 itude %3C -90 %7C%7C l
@@ -1809,33 +1809,35 @@
 tude %3C -
-9
+18
 0 %7C%7C l
-at
+ong
 itude %3E 
 90) %7B%0A  
@@ -1820,33 +1820,34 @@
  %7C%7C longitude %3E 
-9
+18
 0) %7B%0A           
@@ -1885,34 +1885,35 @@
 tion(%22Expected l
-at
+ong
 itude between -9
@@ -1907,32 +1907,34 @@
 de between -
-9
+18
 0 and 
-9
+18
 0, but was %22
@@ -1929,34 +1929,35 @@
 0, but was %22 + l
-at
+ong
 itude);%0A        

Fix order of latitude, longitude.