#!/usr/bin/env python
#
# Copyright 2021 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the',  help='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',  help='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 itertools
import logging
import os
from pathlib import Path
import platform
import shutil
import socket
from environment import get_default_environment
from utils import AOSP_ROOT, run


# A class that is responsible for configuring the server when running the build.
class ServerConfig(object):
  REDIS_SCCACHE_IP = "34.145.83.254"
  REDIS_PORT = 443

  def __in_gce(self):
    """Queries the magic url to determine if we are in GCE"""
    try:
      # TODO(jansene): Remove once windows buildbots are using PY3
      import urllib.request

      with urllib.request.urlopen("http://metadata.google.internal") as r:
        return r.getheader("Metadata-Flavor") == "Google"
    except:
      logging.info("Unable to query magic url, we are not in gce.")
      return False

  def __can_use_redis(self):
    """Tries to connect to the redis cache."""
    try:
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.settimeout(2.5)
      s.connect((ServerConfig.REDIS_SCCACHE_IP, ServerConfig.REDIS_PORT))
      return True
    except:
      logging.exception("Unable to connect to redis, we are not in corp.")
    return False

  def __init__(self, presubmit, args):
    self.args = args
    self.presubmit = presubmit
    self.env = get_default_environment(AOSP_ROOT)
    self.target = platform.system().lower()
    search_dir = Path(
        AOSP_ROOT,
        "prebuilts",
        "android-emulator-build",
        "common",
        "sccache",
        f"{self.target}-x86_64",
    ).absolute()
    self.sccache = shutil.which("sccache", path=search_dir)

  def get_env(self):
    return self.env

  def __enter__(self):
    """Configure cache, report statistics and setup vscode"""
    # Let's make sure we have ninja on the path.

    if self.__in_gce():
      # Use a bucket in gce. Make sure the default service account has R/W
      # access to gs://emu-dev-sccache
      self.env["SCCACHE_GCS_BUCKET"] = "emu-dev-sccache"
      self.env["SCCACHE_GCS_OAUTH_URL"] = (
          "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
      )
      self.env["SCCACHE_GCS_RW_MODE"] = "READ_WRITE"
    elif self.__can_use_redis():
      # Lets try our redis cache.
      self.env["SCCACHE_REDIS"] = "redis//{}:{}/1".format(
          ServerConfig.REDIS_SCCACHE_IP, ServerConfig.REDIS_PORT
      )

    # Configure logging, (debug logging is very verbose, and only needed if
    # you wish to figure out why you have a lot of cache-misses)
    self.env["SCCACHE_LOG"] = "info"
    self.env["SCCACHE_ERROR_LOG"] = os.path.join(
        self.args.dist_dir, "sccache.log"
    )

    # We will terminate sccache upon completion
    self.env["SCCACHE_IDLE_TIMEOUT"] = "0"
    if self.sccache:
      # This will print stats, and launch the server if needed
      run([self.sccache, "--stop-server"], self.env, "scc", AOSP_ROOT, False)
      run([self.sccache, "--start-server"], self.env, "scc", AOSP_ROOT, False)

    return self

  def __exit__(self, exc_type, exc_value, tb):
    """Report cache statistics and stop the server."""
    if self.sccache:
      run([self.sccache, "--stop-server"], self.env, "scc")
