package io.vertx.ext.web.impl;

import io.vertx.codegen.annotations.Nullable;
import io.vertx.ext.web.LanguageHeader;
import io.vertx.ext.web.Locale;

import java.util.List;

public class ParsableLanguageValue extends ParsableHeaderValue implements LanguageHeader{

  private List<String> parsedValues;

  public ParsableLanguageValue(String headerContent) {
    super(headerContent);
    parsedValues = null;
  }

  @Override
  public String tag() {
    return subtag(0);
  }

  @Override
  public String language() {
    String value =  tag();
    return value == null ? null : value.toLowerCase();
  }

  @Override
  public @Nullable String subtag() {
    return subtag(1);
  }

  @Override
  public @Nullable String country() {
    String value = subtag(1);
    return value == null ? null : value.toUpperCase();
  }

  @Override
  public @Nullable String variant() {
    String value = subtag(2);
    return value == null ? null : value.toUpperCase();
  }

  @Override
  public @Nullable String subtag(int level) {
    ensureHeaderProcessed();
    if(level < parsedValues.size()){
      return parsedValues.get(level);
    }
    return null;
  }

  @Override
  public int subtagCount(){
    return parsedValues.size();
  }

  @Override
  protected boolean isMatchedBy2(ParsableHeaderValue matchTry) {
    ParsableLanguageValue myMatchTry = (ParsableLanguageValue) matchTry;
    ensureHeaderProcessed();

    for (int i = 0; i < myMatchTry.parsedValues.size(); i++) {
      String match = myMatchTry.parsedValues.get(i);
      String against = this.parsedValues.get(i);
      if(!"*".equals(match) && !match.equalsIgnoreCase(against)){
        return false;
      }
    }
    return super.isMatchedBy2(myMatchTry);
  }

  @Override
  protected void ensureHeaderProcessed() {
    super.ensureHeaderProcessed();
    parsedValues = HeaderParser.parseLanguageValue(value);
  }

}

@@ -295,16 +295,53 @@
 dValues;
+%0A  private boolean processed = false;
 %0A%0A  publ
@@ -1222,30 +1222,82 @@
 ount()%7B%0A    
-return
+ensureHeaderProcessed();%0A    return parsedValues != null ?
  parsedValue
@@ -1304,16 +1304,20 @@
 s.size()
+ : 0
 ;%0A  %7D%0A%0A 
@@ -1861,24 +1861,71 @@
 ocessed() %7B%0A
+    if(!processed) %7B%0A      processed = true;%0A  
     super.en
@@ -1943,24 +1943,26 @@
 rocessed();%0A
+  
     parsedVa
@@ -2008,15 +2008,21 @@
 value);%0A
+    %7D%0A
   %7D%0A%0A%7D%0A

fix npe when ParsableLanguageValue.subtagCount() is called