// Copyright 2017 Google LLC
//
// 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 "internal/string_view.h"

#include <assert.h>
#include <ctype.h>
#include <string.h>

int CpuFeatures_StringView_IndexOfChar(const StringView view, char c) {
  if (view.ptr && view.size) {
    const char* const found = (const char*)memchr(view.ptr, c, view.size);
    if (found) {
      return (int)(found - view.ptr);
    }
  }
  return -1;
}

int CpuFeatures_StringView_IndexOf(const StringView view,
                                   const StringView sub_view) {
  if (sub_view.size) {
    StringView remainder = view;
    while (remainder.size >= sub_view.size) {
      const int found_index =
          CpuFeatures_StringView_IndexOfChar(remainder, sub_view.ptr[0]);
      if (found_index < 0) break;
      remainder = CpuFeatures_StringView_PopFront(remainder, found_index);
      if (CpuFeatures_StringView_StartsWith(remainder, sub_view)) {
        return (int)(remainder.ptr - view.ptr);
      }
      remainder = CpuFeatures_StringView_PopFront(remainder, 1);
    }
  }
  return -1;
}

bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b) {
  if (a.size == b.size) {
    return a.ptr == b.ptr || memcmp(a.ptr, b.ptr, b.size) == 0;
  }
  return false;
}

bool CpuFeatures_StringView_StartsWith(const StringView a, const StringView b) {
  return a.ptr && b.ptr && b.size && a.size >= b.size
             ? memcmp(a.ptr, b.ptr, b.size) == 0
             : false;
}

StringView CpuFeatures_StringView_PopFront(const StringView str_view,
                                           size_t count) {
  if (count > str_view.size) {
    return kEmptyStringView;
  }
  return view(str_view.ptr + count, str_view.size - count);
}

StringView CpuFeatures_StringView_PopBack(const StringView str_view,
                                          size_t count) {
  if (count > str_view.size) {
    return kEmptyStringView;
  }
  return view(str_view.ptr, str_view.size - count);
}

StringView CpuFeatures_StringView_KeepFront(const StringView str_view,
                                            size_t count) {
  return count <= str_view.size ? view(str_view.ptr, count) : str_view;
}

char CpuFeatures_StringView_Front(const StringView view) {
  assert(view.size);
  assert(view.ptr);
  return view.ptr[0];
}

char CpuFeatures_StringView_Back(const StringView view) {
  assert(view.size);
  return view.ptr[view.size - 1];
}

StringView CpuFeatures_StringView_TrimWhitespace(StringView view) {
  while (view.size && isspace(CpuFeatures_StringView_Front(view)))
    view = CpuFeatures_StringView_PopFront(view, 1);
  while (view.size && isspace(CpuFeatures_StringView_Back(view)))
    view = CpuFeatures_StringView_PopBack(view, 1);
  return view;
}

static int HexValue(const char c) {
  if (c >= '0' && c <= '9') return c - '0';
  if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  if (c >= 'A' && c <= 'F') return c - 'A' + 10;
  return -1;
}

// Returns -1 if view contains non digits.
static int ParsePositiveNumberWithBase(const StringView view, int base) {
  int result = 0;
  StringView remainder = view;
  for (; remainder.size;
       remainder = CpuFeatures_StringView_PopFront(remainder, 1)) {
    const int value = HexValue(CpuFeatures_StringView_Front(remainder));
    if (value < 0 || value >= base) return -1;
    result = (result * base) + value;
  }
  return result;
}

int CpuFeatures_StringView_ParsePositiveNumber(const StringView view) {
  if (view.size) {
    const StringView hex_prefix = str("0x");
    if (CpuFeatures_StringView_StartsWith(view, hex_prefix)) {
      const StringView span_no_prefix =
          CpuFeatures_StringView_PopFront(view, hex_prefix.size);
      return ParsePositiveNumberWithBase(span_no_prefix, 16);
    }
    return ParsePositiveNumberWithBase(view, 10);
  }
  return -1;
}

void CpuFeatures_StringView_CopyString(const StringView src, char* dst,
                                       size_t dst_size) {
  if (dst_size > 0) {
    const size_t max_copy_size = dst_size - 1;
    const size_t copy_size =
        src.size > max_copy_size ? max_copy_size : src.size;
    memcpy(dst, src.ptr, copy_size);
    dst[copy_size] = '\0';
  }
}

bool CpuFeatures_StringView_HasWord(const StringView line,
                                    const char* const word_str) {
  const StringView word = str(word_str);
  StringView remainder = line;
  for (;;) {
    const int index_of_word = CpuFeatures_StringView_IndexOf(remainder, word);
    if (index_of_word < 0) {
      return false;
    } else {
      const StringView before =
          CpuFeatures_StringView_KeepFront(line, index_of_word);
      const StringView after =
          CpuFeatures_StringView_PopFront(line, index_of_word + word.size);
      const bool valid_before =
          before.size == 0 || CpuFeatures_StringView_Back(before) == ' ';
      const bool valid_after =
          after.size == 0 || CpuFeatures_StringView_Front(after) == ' ';
      if (valid_before && valid_after) return true;
      remainder =
          CpuFeatures_StringView_PopFront(remainder, index_of_word + word.size);
    }
  }
  return false;
}

bool CpuFeatures_StringView_GetAttributeKeyValue(const StringView line,
                                                 StringView* key,
                                                 StringView* value) {
  const StringView sep = str(": ");
  const int index_of_separator = CpuFeatures_StringView_IndexOf(line, sep);
  if (index_of_separator < 0) return false;
  *value = CpuFeatures_StringView_TrimWhitespace(
      CpuFeatures_StringView_PopFront(line, index_of_separator + sep.size));
  *key = CpuFeatures_StringView_TrimWhitespace(
      CpuFeatures_StringView_KeepFront(line, index_of_separator));
  return true;
}
