# Copyright 2017 Google Inc. All Rights Reserved.
#
# 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.

import logging
import os

class SdkConfiguration:
  required_sdk_version = '10.0.15063.0'

  # Default Windows SDK bin directory.
  windows_sdk_bin_dir = 'C:\\Program Files (x86)\\Windows Kits\\10\\bin'

  # windows_sdk_host_tools will be set to, eg,
  # 'C:\\Program Files (x86)\\Windows Kits\\10\\bin\10.0.15063.0'

  # windows_sdk_path will be set to, eg
  # 'C:\\Program Files (x86)\\Windows Kits\\10'

  # Default Visual Studio Install directory.
  vs_install_dir = ('C:\\Program Files (x86)\\Microsoft Visual Studio'
                    + '\\2017\\Professional')

  # vs_install_dir_with_version will be set to, eg
  # "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools
  # \MSVC\14.10.25017

  # vs_host_tools_path will be set to, eg
  # "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools
  # \MSVC\14.10.25017\bin\HostX64\x64

  def __init__(self):
    # Maybe override Windows SDK bin directory with environment variable.
    windows_sdk_bin_var = 'WindowsSdkBinPath'
    if windows_sdk_bin_var in os.environ:
      self.windows_sdk_bin_dir = os.environ[windows_sdk_bin_var]
    elif not os.path.exists(self.windows_sdk_bin_dir):
      # If the above fails, this is our last guess.
      self.windows_sdk_bin_dir = self.windows_sdk_bin_dir.replace(
        'Program Files (x86)', 'mappedProgramFiles')

    self.windows_sdk_host_tools = os.path.join(
        self.windows_sdk_bin_dir, self.required_sdk_version, 'x64')

    self.windows_sdk_path = os.path.dirname(self.windows_sdk_bin_dir)

    # Maybe override Visual Studio install directory with environment variable.
    vs_install_dir_var = 'VSINSTALLDIR'
    if vs_install_dir_var in os.environ:
      self.vs_install_dir = os.environ[vs_install_dir_var]
    elif not os.path.exists(self.vs_install_dir):
      # If the above fails, this is our last guess.
      self.vs_install_dir = self.vs_install_dir.replace('Program Files (x86)',
                                                        'mappedProgramFiles')

    self.vs_install_dir_with_version = (self.vs_install_dir
        + '\\VC\\Tools\\MSVC' + '\\14.10.25017')
    self.vs_host_tools_path = (self.vs_install_dir_with_version
        + '\\bin\\HostX64\\x64')

    if not os.path.exists(self.vs_host_tools_path):
      logging.critical('Expected Visual Studio path \"%s\" not found.',
                       self.vs_cl_path)
    self._CheckWindowsSdkVersion()

  def _CheckWindowsSdkVersion(self):
    if os.path.exists(self.windows_sdk_host_tools):
      return True

    if os.path.exists(self.windows_sdk_bin_dir):
      contents = os.listdir(self.windows_sdk_bin_dir)
      contents = [content for content in contents
                  if os.path.isdir(
                    os.path.join(self.windows_sdk_bin_dir, content))]
      non_sdk_dirs = ['arm', 'arm64', 'x64', 'x86']
      installed_sdks = [content for content in contents
                        if content not in non_sdk_dirs]
      logging.critical('Windows SDK versions \"%s\" found." \"%s\" required.',
                       installed_sdks, self.required_sdk_version)
    else:
      logging.critical('Windows SDK versions \"%s\" required.',
                       self.required_sdk_version)
    return False

