/*
 * 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 <charconv>
#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* const 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;
  }

  const char* start = name + 1;
  const char* s = start;
  while (*s >= '0' && *s <= '9') s++;
  if (s == start) return false;

  uint16_t sdkVersion = 0;
  auto result = std::from_chars(start, s, sdkVersion);
  if (result.ec != std::errc()) {
    return false;
  }

  if (out) {
    out->sdkVersion = sdkVersion;
  }

  if (*s == 0) {
    // No minor version specified
    out->minorVersion = 0;
    return true;
  }

  // Minor version starts after '.'
  if (*s != '.') {
    return false;
  }

  start = s + 1;
  s = start;
  while (*s >= '0' && *s <= '9') {
    s++;
  }
  if (s == start || *s != 0) {
    return false;
  }

  uint16_t minorVersion = 0;
  result = std::from_chars(start, s, minorVersion);
  if (result.ec != std::errc()) {
    return false;
  }

  // sdkVersion of 0 is not really valid, even though we allow it to be parsed. Therefore if it's 0,
  // we shouldn't allow a minorVersion (unless it's also 0).
  if (sdkVersion == 0 && minorVersion != 0) {
    return false;
  }

  if (out) {
    out->minorVersion = minorVersion;
  }

  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 != nullptr) {
    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;
    config->minorVersion = 0;
  }
}

ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
  ConfigDescription copy = *this;
  copy.version = 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.c_str(), 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
