# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os

from .config import Config
from .gn import BuildDirectoryForConfig

class Paths(object):
  """Provides commonly used paths"""

  def __init__(self, config=None, build_dir=None):
    """Specify either a config or a build_dir to generate paths to binary
    artifacts."""
    self.src_root = os.path.abspath(os.path.join(__file__,
      os.pardir, os.pardir, os.pardir, os.pardir))
    self.mojo_dir = os.path.join(self.src_root, "mojo")
    self.adb_path = os.path.join(self.src_root, 'third_party', 'android_tools',
                                 'sdk', 'platform-tools', 'adb')

    self.go_tool_path = None
    if config:
      if (config.target_os == Config.OS_LINUX and
          config.target_cpu == Config.ARCH_X64):
        self.go_tool_path = os.path.join(self.src_root, "third_party",
            "go", "tool", "linux_amd64", "bin", "go")
      elif config.target_os == Config.OS_ANDROID:
        self.go_tool_path = os.path.join(self.src_root, "third_party",
            "go", "tool", "android_arm", "bin", "go")

    if config:
      self.build_dir = BuildDirectoryForConfig(config, self.src_root)
    elif build_dir is not None:
      self.build_dir = os.path.abspath(build_dir)
    else:
      self.build_dir = None

    if self.build_dir is not None:
      self.mojo_shell_path = os.path.join(self.build_dir, "mojo_shell")
      self.mojo_shell_child_path = os.path.join(self.build_dir,
          "mojo_shell_child")
      self.dart_snapshotter_path = os.path.join(
          self.build_dir, "dart_snapshotter")
      self.sky_shell_path = os.path.join(self.build_dir, "sky_shell")
      # TODO(vtl): Use the host OS here, since |config| may not be available.
      # In any case, if the target is Windows, but the host isn't, using
      # |os.path| isn't correct....
      if Config.GetHostOS() == Config.OS_WINDOWS:
        self.mojo_shell_path += ".exe"
        self.mojo_shell_child_path += ".exe"
        self.sky_shell_path += ".exe"
        self.dart_snapshotter_path += ".exe"
      if config and config.target_os == Config.OS_ANDROID:
        self.target_mojo_shell_path = os.path.join(self.build_dir,
                                                   "apks",
                                                   "MojoShell.apk")
        self.target_mojo_shell_binaries = [self.target_mojo_shell_path]
        # dart_snapshotter only runs on the host platform. There is no build to
        # run on Android.
        self.target_dart_snapshotter_path = None
        self.target_sky_shell_path = os.path.join(self.build_dir,
                                                  "apks",
                                                  "SkyDemo.apk")
      else:
        self.target_mojo_shell_path = self.mojo_shell_path
        self.target_mojo_shell_binaries = [self.mojo_shell_path,
                                           self.mojo_shell_child_path]
        self.target_dart_snapshotter_path = self.dart_snapshotter_path
        self.target_sky_shell_path = self.sky_shell_path
    else:
      self.mojo_shell_path = None
      self.dart_snapshotter_path = None
      self.sky_shell_path = None
      self.target_mojo_shell_path = None
      self.target_dart_snapshotter_path = None
      self.target_sky_shell_path = None

  def RelPath(self, path):
    """Returns the given path, relative to the current directory."""
    return os.path.relpath(path)

  def SrcRelPath(self, path):
    """Returns the given path, relative to self.src_root."""
    return os.path.relpath(path, self.src_root)

  def FileFromUrl(self, url):
    """Given an app URL (<scheme>:<appname>), return 'build_dir/appname.mojo'.
    If self.build_dir is None, just return appname.mojo
    """
    (_, name) = url.split(':')
    if self.build_dir:
      return os.path.join(self.build_dir, name + '.mojo')
    return name + '.mojo'

  @staticmethod
  def IsValidAppUrl(url):
    """Returns False if url is malformed, True otherwise."""
    try:
      return len(url.split(':')) == 2
    except ValueError:
      return False
