// Copyright 2017 Google Inc.
//
// 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 "cpuinfo_aarch64.h"

#include "internal/filesystem.h"
#include "internal/hwcaps.h"
#include "internal/linux_features_aggregator.h"
#include "internal/stack_line_reader.h"
#include "internal/string_view.h"

#include <ctype.h>

DECLARE_SETTER(Aarch64Features, fp)
DECLARE_SETTER(Aarch64Features, asimd)
DECLARE_SETTER(Aarch64Features, aes)
DECLARE_SETTER(Aarch64Features, pmull)
DECLARE_SETTER(Aarch64Features, sha1)
DECLARE_SETTER(Aarch64Features, sha2)
DECLARE_SETTER(Aarch64Features, crc32)

static const CapabilityConfig kConfigs[] = {
    {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp},           //
    {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd},  //
    {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes},        //
    {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull},  //
    {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1},     //
    {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2},     //
    {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32},  //
};

static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);

static bool HandleAarch64Line(const LineResult result,
                              Aarch64Info* const info) {
  StringView line = result.line;
  StringView key, value;
  if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
    if (CpuFeatures_StringView_IsEquals(key, str("Features"))) {
      CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features);
    } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) {
      info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value);
    } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) {
      info->variant = CpuFeatures_StringView_ParsePositiveNumber(value);
    } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) {
      info->part = CpuFeatures_StringView_ParsePositiveNumber(value);
    } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) {
      info->revision = CpuFeatures_StringView_ParsePositiveNumber(value);
    }
  }
  return !result.eof;
}

static void FillProcCpuInfoData(Aarch64Info* const info) {
  const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
  if (fd >= 0) {
    StackLineReader reader;
    StackLineReader_Initialize(&reader, fd);
    for (;;) {
      if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) {
        break;
      }
    }
    CpuFeatures_CloseFile(fd);
  }
}

static const Aarch64Info kEmptyAarch64Info;

Aarch64Info GetAarch64Info(void) {
  // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
  // have some information if the executable is sandboxed (aka no access to
  // /proc/cpuinfo).
  Aarch64Info info = kEmptyAarch64Info;

  FillProcCpuInfoData(&info);
  CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
                                 CpuFeatures_GetHardwareCapabilities(),
                                 &info.features);

  return info;
}

////////////////////////////////////////////////////////////////////////////////
// Introspection functions

int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
                                Aarch64FeaturesEnum value) {
  switch (value) {
    case AARCH64_FP:
      return features->fp;
    case AARCH64_ASIMD:
      return features->asimd;
    case AARCH64_AES:
      return features->aes;
    case AARCH64_PMULL:
      return features->pmull;
    case AARCH64_SHA1:
      return features->sha1;
    case AARCH64_SHA2:
      return features->sha2;
    case AARCH64_CRC32:
      return features->crc32;
    case AARCH64_LAST_:
      break;
  }
  return false;
}

const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) {
  switch (value) {
    case AARCH64_FP:
      return "fp";
    case AARCH64_ASIMD:
      return "asimd";
    case AARCH64_AES:
      return "aes";
    case AARCH64_PMULL:
      return "pmull";
    case AARCH64_SHA1:
      return "sha1";
    case AARCH64_SHA2:
      return "sha2";
    case AARCH64_CRC32:
      return "crc32";
    case AARCH64_LAST_:
      break;
  }
  return "unknown feature";
}
