/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "androidfw/ConfigDescription.h"
#include "androidfw/Locale.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
#include "androidfw/Util.h"

#include <string>
#include <string_view>
#include <vector>

namespace android {

static const char* kWildcardName = "any";

const ConfigDescription& ConfigDescription::DefaultConfig() {
  static ConfigDescription config = {};
  return config;
}

static bool parseMcc(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->mcc = 0;
    return true;
  }
  const char* c = name;
  if (*c != 'm') return false;
  c++;
  if (*c != 'c') return false;
  c++;
  if (*c != 'c') return false;
  c++;

  const char* val = c;

  while (*c >= '0' && *c <= '9') {
    c++;
  }
  if (*c != 0) return false;
  if (c - val != 3) return false;

  int d = atoi(val);
  if (d != 0) {
    if (out) out->mcc = d;
    return true;
  }

  return false;
}

static bool parseMnc(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->mnc = 0;
    return true;
  }
  const char* c = name;
  if (*c != 'm') return false;
  c++;
  if (*c != 'n') return false;
  c++;
  if (*c != 'c') return false;
  c++;

  const char* val = c;

  while (*c >= '0' && *c <= '9') {
    c++;
  }
  if (*c != 0) return false;
  if (c - val == 0 || c - val > 3) return false;

  if (out) {
    out->mnc = atoi(val);
    if (out->mnc == 0) {
      out->mnc = ACONFIGURATION_MNC_ZERO;
    }
  }

  return true;
}

static bool parseGrammaticalInflection(const std::string& name, ResTable_config* out) {
  using namespace std::literals;
  if (name == "feminine"sv) {
    if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_FEMININE;
    return true;
  }
  if (name == "masculine"sv) {
    if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_MASCULINE;
    return true;
  }
  if (name == "neuter"sv) {
    if (out) out->grammaticalInflection = ResTable_config::GRAMMATICAL_GENDER_NEUTER;
    return true;
  }
  return false;
}

static bool parseLayoutDirection(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
          ResTable_config::LAYOUTDIR_ANY;
    return true;
  } else if (strcmp(name, "ldltr") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
          ResTable_config::LAYOUTDIR_LTR;
    return true;
  } else if (strcmp(name, "ldrtl") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_LAYOUTDIR) |
          ResTable_config::LAYOUTDIR_RTL;
    return true;
  }

  return false;
}

static bool parseScreenLayoutSize(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
          ResTable_config::SCREENSIZE_ANY;
    return true;
  } else if (strcmp(name, "small") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
          ResTable_config::SCREENSIZE_SMALL;
    return true;
  } else if (strcmp(name, "normal") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
          ResTable_config::SCREENSIZE_NORMAL;
    return true;
  } else if (strcmp(name, "large") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
          ResTable_config::SCREENSIZE_LARGE;
    return true;
  } else if (strcmp(name, "xlarge") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENSIZE) |
          ResTable_config::SCREENSIZE_XLARGE;
    return true;
  }

  return false;
}

static bool parseScreenLayoutLong(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
          ResTable_config::SCREENLONG_ANY;
    return true;
  } else if (strcmp(name, "long") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
          ResTable_config::SCREENLONG_YES;
    return true;
  } else if (strcmp(name, "notlong") == 0) {
    if (out)
      out->screenLayout =
          (out->screenLayout & ~ResTable_config::MASK_SCREENLONG) |
          ResTable_config::SCREENLONG_NO;
    return true;
  }

  return false;
}

static bool parseScreenRound(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->screenLayout2 =
          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
          ResTable_config::SCREENROUND_ANY;
    return true;
  } else if (strcmp(name, "round") == 0) {
    if (out)
      out->screenLayout2 =
          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
          ResTable_config::SCREENROUND_YES;
    return true;
  } else if (strcmp(name, "notround") == 0) {
    if (out)
      out->screenLayout2 =
          (out->screenLayout2 & ~ResTable_config::MASK_SCREENROUND) |
          ResTable_config::SCREENROUND_NO;
    return true;
  }
  return false;
}

static bool parseWideColorGamut(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
          ResTable_config::WIDE_COLOR_GAMUT_ANY;
    return true;
  } else if (strcmp(name, "widecg") == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
          ResTable_config::WIDE_COLOR_GAMUT_YES;
    return true;
  } else if (strcmp(name, "nowidecg") == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) |
          ResTable_config::WIDE_COLOR_GAMUT_NO;
    return true;
  }
  return false;
}

static bool parseHdr(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_HDR) |
          ResTable_config::HDR_ANY;
    return true;
  } else if (strcmp(name, "highdr") == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_HDR) |
          ResTable_config::HDR_YES;
    return true;
  } else if (strcmp(name, "lowdr") == 0) {
    if (out)
      out->colorMode =
          (out->colorMode & ~ResTable_config::MASK_HDR) |
          ResTable_config::HDR_NO;
    return true;
  }
  return false;
}

static bool parseOrientation(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->orientation = out->ORIENTATION_ANY;
    return true;
  } else if (strcmp(name, "port") == 0) {
    if (out) out->orientation = out->ORIENTATION_PORT;
    return true;
  } else if (strcmp(name, "land") == 0) {
    if (out) out->orientation = out->ORIENTATION_LAND;
    return true;
  } else if (strcmp(name, "square") == 0) {
    if (out) out->orientation = out->ORIENTATION_SQUARE;
    return true;
  }

  return false;
}

static bool parseUiModeType(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_ANY;
    return true;
  } else if (strcmp(name, "desk") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_DESK;
    return true;
  } else if (strcmp(name, "car") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_CAR;
    return true;
  } else if (strcmp(name, "television") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_TELEVISION;
    return true;
  } else if (strcmp(name, "appliance") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_APPLIANCE;
    return true;
  } else if (strcmp(name, "watch") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_WATCH;
    return true;
  } else if (strcmp(name, "vrheadset") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_TYPE) |
                    ResTable_config::UI_MODE_TYPE_VR_HEADSET;
    return true;
  }

  return false;
}

static bool parseUiModeNight(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
                    ResTable_config::UI_MODE_NIGHT_ANY;
    return true;
  } else if (strcmp(name, "night") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
                    ResTable_config::UI_MODE_NIGHT_YES;
    return true;
  } else if (strcmp(name, "notnight") == 0) {
    if (out)
      out->uiMode = (out->uiMode & ~ResTable_config::MASK_UI_MODE_NIGHT) |
                    ResTable_config::UI_MODE_NIGHT_NO;
    return true;
  }

  return false;
}

static bool parseDensity(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->density = ResTable_config::DENSITY_DEFAULT;
    return true;
  }

  if (strcmp(name, "anydpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_ANY;
    return true;
  }

  if (strcmp(name, "nodpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_NONE;
    return true;
  }

  if (strcmp(name, "ldpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_LOW;
    return true;
  }

  if (strcmp(name, "mdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_MEDIUM;
    return true;
  }

  if (strcmp(name, "tvdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_TV;
    return true;
  }

  if (strcmp(name, "hdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_HIGH;
    return true;
  }

  if (strcmp(name, "xhdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_XHIGH;
    return true;
  }

  if (strcmp(name, "xxhdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_XXHIGH;
    return true;
  }

  if (strcmp(name, "xxxhdpi") == 0) {
    if (out) out->density = ResTable_config::DENSITY_XXXHIGH;
    return true;
  }

  char* c = (char*)name;
  while (*c >= '0' && *c <= '9') {
    c++;
  }

  // check that we have 'dpi' after the last digit.
  if (toupper(c[0]) != 'D' || toupper(c[1]) != 'P' || toupper(c[2]) != 'I' ||
      c[3] != 0) {
    return false;
  }

  // temporarily replace the first letter with \0 to
  // use atoi.
  char tmp = c[0];
  c[0] = '\0';

  int d = atoi(name);
  c[0] = tmp;

  if (d != 0) {
    if (out) out->density = d;
    return true;
  }

  return false;
}

static bool parseTouchscreen(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->touchscreen = out->TOUCHSCREEN_ANY;
    return true;
  } else if (strcmp(name, "notouch") == 0) {
    if (out) out->touchscreen = out->TOUCHSCREEN_NOTOUCH;
    return true;
  } else if (strcmp(name, "stylus") == 0) {
    if (out) out->touchscreen = out->TOUCHSCREEN_STYLUS;
    return true;
  } else if (strcmp(name, "finger") == 0) {
    if (out) out->touchscreen = out->TOUCHSCREEN_FINGER;
    return true;
  }

  return false;
}

static bool parseKeysHidden(const char* name, ResTable_config* out) {
  uint8_t mask = 0;
  uint8_t value = 0;
  if (strcmp(name, kWildcardName) == 0) {
    mask = ResTable_config::MASK_KEYSHIDDEN;
    value = ResTable_config::KEYSHIDDEN_ANY;
  } else if (strcmp(name, "keysexposed") == 0) {
    mask = ResTable_config::MASK_KEYSHIDDEN;
    value = ResTable_config::KEYSHIDDEN_NO;
  } else if (strcmp(name, "keyshidden") == 0) {
    mask = ResTable_config::MASK_KEYSHIDDEN;
    value = ResTable_config::KEYSHIDDEN_YES;
  } else if (strcmp(name, "keyssoft") == 0) {
    mask = ResTable_config::MASK_KEYSHIDDEN;
    value = ResTable_config::KEYSHIDDEN_SOFT;
  }

  if (mask != 0) {
    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
    return true;
  }

  return false;
}

static bool parseKeyboard(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->keyboard = out->KEYBOARD_ANY;
    return true;
  } else if (strcmp(name, "nokeys") == 0) {
    if (out) out->keyboard = out->KEYBOARD_NOKEYS;
    return true;
  } else if (strcmp(name, "qwerty") == 0) {
    if (out) out->keyboard = out->KEYBOARD_QWERTY;
    return true;
  } else if (strcmp(name, "12key") == 0) {
    if (out) out->keyboard = out->KEYBOARD_12KEY;
    return true;
  }

  return false;
}

static bool parseNavHidden(const char* name, ResTable_config* out) {
  uint8_t mask = 0;
  uint8_t value = 0;
  if (strcmp(name, kWildcardName) == 0) {
    mask = ResTable_config::MASK_NAVHIDDEN;
    value = ResTable_config::NAVHIDDEN_ANY;
  } else if (strcmp(name, "navexposed") == 0) {
    mask = ResTable_config::MASK_NAVHIDDEN;
    value = ResTable_config::NAVHIDDEN_NO;
  } else if (strcmp(name, "navhidden") == 0) {
    mask = ResTable_config::MASK_NAVHIDDEN;
    value = ResTable_config::NAVHIDDEN_YES;
  }

  if (mask != 0) {
    if (out) out->inputFlags = (out->inputFlags & ~mask) | value;
    return true;
  }

  return false;
}

static bool parseNavigation(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) out->navigation = out->NAVIGATION_ANY;
    return true;
  } else if (strcmp(name, "nonav") == 0) {
    if (out) out->navigation = out->NAVIGATION_NONAV;
    return true;
  } else if (strcmp(name, "dpad") == 0) {
    if (out) out->navigation = out->NAVIGATION_DPAD;
    return true;
  } else if (strcmp(name, "trackball") == 0) {
    if (out) out->navigation = out->NAVIGATION_TRACKBALL;
    return true;
  } else if (strcmp(name, "wheel") == 0) {
    if (out) out->navigation = out->NAVIGATION_WHEEL;
    return true;
  }

  return false;
}

static bool parseScreenSize(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) {
      out->screenWidth = out->SCREENWIDTH_ANY;
      out->screenHeight = out->SCREENHEIGHT_ANY;
    }
    return true;
  }

  const char* x = name;
  while (*x >= '0' && *x <= '9') x++;
  if (x == name || *x != 'x') return false;
  std::string xName(name, x - name);
  x++;

  const char* y = x;
  while (*y >= '0' && *y <= '9') y++;
  if (y == name || *y != 0) return false;
  std::string yName(x, y - x);

  uint16_t w = (uint16_t)atoi(xName.c_str());
  uint16_t h = (uint16_t)atoi(yName.c_str());
  if (w < h) {
    return false;
  }

  if (out) {
    out->screenWidth = w;
    out->screenHeight = h;
  }

  return true;
}

static bool parseSmallestScreenWidthDp(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) {
      out->smallestScreenWidthDp = out->SCREENWIDTH_ANY;
    }
    return true;
  }

  if (*name != 's') return false;
  name++;
  if (*name != 'w') return false;
  name++;
  const char* x = name;
  while (*x >= '0' && *x <= '9') x++;
  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
  std::string xName(name, x - name);

  if (out) {
    out->smallestScreenWidthDp = (uint16_t)atoi(xName.c_str());
  }

  return true;
}

static bool parseScreenWidthDp(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) {
      out->screenWidthDp = out->SCREENWIDTH_ANY;
    }
    return true;
  }

  if (*name != 'w') return false;
  name++;
  const char* x = name;
  while (*x >= '0' && *x <= '9') x++;
  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
  std::string xName(name, x - name);

  if (out) {
    out->screenWidthDp = (uint16_t)atoi(xName.c_str());
  }

  return true;
}

static bool parseScreenHeightDp(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) {
      out->screenHeightDp = out->SCREENWIDTH_ANY;
    }
    return true;
  }

  if (*name != 'h') return false;
  name++;
  const char* x = name;
  while (*x >= '0' && *x <= '9') x++;
  if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
  std::string xName(name, x - name);

  if (out) {
    out->screenHeightDp = (uint16_t)atoi(xName.c_str());
  }

  return true;
}

static bool parseVersion(const char* name, ResTable_config* out) {
  if (strcmp(name, kWildcardName) == 0) {
    if (out) {
      out->sdkVersion = out->SDKVERSION_ANY;
      out->minorVersion = out->MINORVERSION_ANY;
    }
    return true;
  }

  if (*name != 'v') {
    return false;
  }

  name++;
  const char* s = name;
  while (*s >= '0' && *s <= '9') s++;
  if (s == name || *s != 0) return false;
  std::string sdkName(name, s - name);

  if (out) {
    out->sdkVersion = (uint16_t)atoi(sdkName.c_str());
    out->minorVersion = 0;
  }

  return true;
}

bool ConfigDescription::Parse(StringPiece str, ConfigDescription* out) {
  std::vector<std::string> parts = util::SplitAndLowercase(str, '-');

  ConfigDescription config;
  ssize_t parts_consumed = 0;
  LocaleValue locale;

  const auto parts_end = parts.end();
  auto part_iter = parts.begin();

  if (str.size() == 0) {
    goto success;
  }

  if (parseMcc(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseMnc(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  // Locale spans a few '-' separators, so we let it
  // control the index.
  parts_consumed = locale.InitFromParts(part_iter, parts_end);
  if (parts_consumed < 0) {
    return false;
  } else {
    locale.WriteTo(&config);
    part_iter += parts_consumed;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseGrammaticalInflection(*part_iter, &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseLayoutDirection(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseSmallestScreenWidthDp(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenWidthDp(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenHeightDp(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenLayoutSize(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenLayoutLong(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenRound(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseWideColorGamut(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseHdr(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseOrientation(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseUiModeType(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseUiModeNight(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseDensity(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseTouchscreen(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseKeysHidden(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseKeyboard(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseNavHidden(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseNavigation(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseScreenSize(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  if (parseVersion(part_iter->c_str(), &config)) {
    ++part_iter;
    if (part_iter == parts_end) {
      goto success;
    }
  }

  // Unrecognized.
  return false;

success:
  if (out != NULL) {
    ApplyVersionForCompatibility(&config);
    *out = config;
  }
  return true;
}

void ConfigDescription::ApplyVersionForCompatibility(
    ConfigDescription* config) {
  uint16_t min_sdk = 0;
  if (config->grammaticalInflection != 0) {
    min_sdk = SDK_U;
  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE)
                == ResTable_config::UI_MODE_TYPE_VR_HEADSET ||
            config->colorMode & ResTable_config::MASK_WIDE_COLOR_GAMUT ||
            config->colorMode & ResTable_config::MASK_HDR) {
    min_sdk = SDK_O;
  } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) {
    min_sdk = SDK_MARSHMALLOW;
  } else if (config->density == ResTable_config::DENSITY_ANY) {
    min_sdk = SDK_LOLLIPOP;
  } else if (config->smallestScreenWidthDp !=
                 ResTable_config::SCREENWIDTH_ANY ||
             config->screenWidthDp != ResTable_config::SCREENWIDTH_ANY ||
             config->screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
    min_sdk = SDK_HONEYCOMB_MR2;
  } else if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) !=
                 ResTable_config::UI_MODE_TYPE_ANY ||
             (config->uiMode & ResTable_config::MASK_UI_MODE_NIGHT) !=
                 ResTable_config::UI_MODE_NIGHT_ANY) {
    min_sdk = SDK_FROYO;
  } else if ((config->screenLayout & ResTable_config::MASK_SCREENSIZE) !=
                 ResTable_config::SCREENSIZE_ANY ||
             (config->screenLayout & ResTable_config::MASK_SCREENLONG) !=
                 ResTable_config::SCREENLONG_ANY ||
             config->density != ResTable_config::DENSITY_DEFAULT) {
    min_sdk = SDK_DONUT;
  }

  if (min_sdk > config->sdkVersion) {
    config->sdkVersion = min_sdk;
  }
}

ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
  ConfigDescription copy = *this;
  copy.sdkVersion = 0;
  return copy;
}

std::string ConfigDescription::GetBcp47LanguageTag(bool canonicalize) const {
  char locale[RESTABLE_MAX_LOCALE_LEN];
  getBcp47Locale(locale, canonicalize);
  return std::string(locale);
}

std::string ConfigDescription::to_string() const {
  const String8 str = toString();
  return std::string(str.string(), str.size());
}

bool ConfigDescription::Dominates(const ConfigDescription& o) const {
  if (*this == o) {
    return true;
  }

  // Locale de-duping is not-trivial, disable for now (b/62409213).
  // We must also disable de-duping for all configuration qualifiers with precedence higher than
  // locale (b/171892595)
  if (diff(o) & (CONFIG_LOCALE | CONFIG_MCC | CONFIG_MNC)) {
    return false;
  }

  if (*this == DefaultConfig()) {
    return true;
  }

  return MatchWithDensity(o) && !o.MatchWithDensity(*this) &&
         !isMoreSpecificThan(o) && !o.HasHigherPrecedenceThan(*this);
}

bool ConfigDescription::HasHigherPrecedenceThan(
    const ConfigDescription& o) const {
  // The order of the following tests defines the importance of one
  // configuration parameter over another. Those tests first are more
  // important, trumping any values in those following them.
  // The ordering should be the same as ResTable_config#isBetterThan.
  if (mcc || o.mcc) return (!o.mcc);
  if (mnc || o.mnc) return (!o.mnc);
  if (language[0] || o.language[0]) return (!o.language[0]);
  if (country[0] || o.country[0]) return (!o.country[0]);
  // Script and variant require either a language or country, both of which
  // have higher precedence.
  if (grammaticalInflection || o.grammaticalInflection) return !o.grammaticalInflection;
  if ((screenLayout | o.screenLayout) & MASK_LAYOUTDIR) {
    return !(o.screenLayout & MASK_LAYOUTDIR);
  }
  if (smallestScreenWidthDp || o.smallestScreenWidthDp)
    return (!o.smallestScreenWidthDp);
  if (screenWidthDp || o.screenWidthDp) return (!o.screenWidthDp);
  if (screenHeightDp || o.screenHeightDp) return (!o.screenHeightDp);
  if ((screenLayout | o.screenLayout) & MASK_SCREENSIZE) {
    return !(o.screenLayout & MASK_SCREENSIZE);
  }
  if ((screenLayout | o.screenLayout) & MASK_SCREENLONG) {
    return !(o.screenLayout & MASK_SCREENLONG);
  }
  if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) {
    return !(o.screenLayout2 & MASK_SCREENROUND);
  }
  if ((colorMode | o.colorMode) & MASK_HDR) {
    return !(o.colorMode & MASK_HDR);
  }
  if ((colorMode | o.colorMode) & MASK_WIDE_COLOR_GAMUT) {
    return !(o.colorMode & MASK_WIDE_COLOR_GAMUT);
  }
  if (orientation || o.orientation) return (!o.orientation);
  if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) {
    return !(o.uiMode & MASK_UI_MODE_TYPE);
  }
  if ((uiMode | o.uiMode) & MASK_UI_MODE_NIGHT) {
    return !(o.uiMode & MASK_UI_MODE_NIGHT);
  }
  if (density || o.density) return (!o.density);
  if (touchscreen || o.touchscreen) return (!o.touchscreen);
  if ((inputFlags | o.inputFlags) & MASK_KEYSHIDDEN) {
    return !(o.inputFlags & MASK_KEYSHIDDEN);
  }
  if ((inputFlags | o.inputFlags) & MASK_NAVHIDDEN) {
    return !(o.inputFlags & MASK_NAVHIDDEN);
  }
  if (keyboard || o.keyboard) return (!o.keyboard);
  if (navigation || o.navigation) return (!o.navigation);
  if (screenWidth || o.screenWidth) return (!o.screenWidth);
  if (screenHeight || o.screenHeight) return (!o.screenHeight);
  if (sdkVersion || o.sdkVersion) return (!o.sdkVersion);
  if (minorVersion || o.minorVersion) return (!o.minorVersion);
  // Both configurations have nothing defined except some possible future
  // value. Returning the comparison of the two configurations is a
  // "best effort" at this point to protect against incorrect dominations.
  return *this != o;
}

bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const {
  // This method should be updated as new configuration parameters are
  // introduced (e.g. screenConfig2).
  auto pred = [](const uint32_t a, const uint32_t b) -> bool {
    return a == 0 || b == 0 || a == b;
  };
  // The values here can be found in ResTable_config#match. Density and range
  // values can't lead to conflicts, and are ignored.
  return !pred(mcc, o.mcc) || !pred(mnc, o.mnc) || !pred(locale, o.locale) ||
         !pred(grammaticalInflection, o.grammaticalInflection) ||
         !pred(screenLayout & MASK_LAYOUTDIR,
               o.screenLayout & MASK_LAYOUTDIR) ||
         !pred(screenLayout & MASK_SCREENLONG,
               o.screenLayout & MASK_SCREENLONG) ||
         !pred(uiMode & MASK_UI_MODE_TYPE, o.uiMode & MASK_UI_MODE_TYPE) ||
         !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) ||
         !pred(screenLayout2 & MASK_SCREENROUND,
               o.screenLayout2 & MASK_SCREENROUND) ||
         !pred(colorMode & MASK_HDR, o.colorMode & MASK_HDR) ||
         !pred(colorMode & MASK_WIDE_COLOR_GAMUT,
               o.colorMode & MASK_WIDE_COLOR_GAMUT) ||
         !pred(orientation, o.orientation) ||
         !pred(touchscreen, o.touchscreen) ||
         !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) ||
         !pred(inputFlags & MASK_NAVHIDDEN, o.inputFlags & MASK_NAVHIDDEN) ||
         !pred(keyboard, o.keyboard) || !pred(navigation, o.navigation);
}

bool ConfigDescription::IsCompatibleWith(const ConfigDescription& o) const {
  return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
}

}  // namespace android
