# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. 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
import re
import test
import utils

from os.path import join, exists


class Error(Exception):
  pass


class Co19TestCase(test.TestCase):
  def __init__(self, path, context, filename, mode, arch):
    super(Co19TestCase, self).__init__(context, path)
    self.filename = filename
    self.mode = mode
    self.arch = arch
    self._is_negative = None

  def IsNegative(self):
    if self._is_negative is None :
      contents = self.GetSource()
      for tag in ('@compile-error','@static-type-error', 
                  '@dynamic-type-error', '@runtime-error'):
        if tag in contents:
          self._is_negative = True
          break
      else :
        self._is_negative = False

    return self._is_negative

  def GetLabel(self):
    return "%s%s %s" % (self.mode, self.arch, "/".join(self.path))

  def GetCommand(self):
    # Parse the options by reading the .dash source file.
    source = self.GetSource()
    vm_options = utils.ParseTestOptions(test.VM_OPTIONS_PATTERN, source,
                                        self.context.workspace)
    dash_options = utils.ParseTestOptions(test.DASH_OPTIONS_PATTERN, source,
                                          self.context.workspace)

    # Combine everything into a command array and return it.
    command = self.context.GetDash(self.mode, self.arch)
    if vm_options: command += vm_options
    if dash_options: command += dash_options
    else:
      command += [ '--', self.filename]
      if self.filename.endswith(".dash"):
        # add also CO19 specific header
        headerPath = self.GetSpecificHeader()
        command += [ headerPath, '--', "Main.main" ]
    return command

  _SUITE_ROOT = 'co19' 
  def GetSpecificHeader(self):
    path = self.filename[ : self.filename.rfind(self._SUITE_ROOT)]
    return join(path, self._SUITE_ROOT)

  def GetName(self):
    return self.path[-1]

  def GetPath(self):
    return os.path.dirname(self.filename)

  def GetSource(self):
    return file(self.filename).read()


class Co19TestConfiguration(test.TestConfiguration):
  def __init__(self, context, root):
    super(Co19TestConfiguration, self).__init__(context, root)

  def ListTests(self, current_path, path, mode, arch):
    tests = []
    src_dir = join(self.root, "src")
    strip = len(src_dir.split(os.path.sep))
    for root, dirs, files in os.walk(src_dir):
      ignore_dirs = [d for d in dirs if d.startswith('.')]
      for d in ignore_dirs:
        dirs.remove(d)
      for f in [x for x in files if self.IsTest(x)]:
        test_path = [] + current_path
        test_path.extend(root.split(os.path.sep)[strip:])
        test_name = short_name = f

        # shotlen test_name
        # remove repeats
        if short_name.startswith(test_path[-1]):
          short_name = short_name[len(test_path[-1]) : ]

        # remove suffixes
        if short_name.endswith(".dash"):
          short_name = short_name[:-5]  # Remove .dash suffix.
        # now .app suffix discarded at self.IsTest() 
        #elif short_name.endswith(".app"):
        #  short_name = short_name[:-4]  # Remove .app suffix.
        else:
          raise Error('Unknown suffix in "%s", fix IsTest() predicate' % f)

        
        while short_name.startswith('_'):
          short_name = short_name[1:]
        
        test_path.extend(short_name.split('_'))

        # test full name and shorted name matches given path pattern
        if self.Contains(path, test_path): pass
        elif self.Contains(path, test_path + [test_name]): pass
        else:
          continue
 
        tests.append(Co19TestCase(test_path,
                                  self.context,
                                  join(root, f),
                                  mode,
                                  arch))
    return tests

  _TESTNAME_PATTERN = re.compile(r'.*_t[0-9]{2}\.dash$')
  def IsTest(self, name):
    return self._TESTNAME_PATTERN.match(name)

  def GetTestStatus(self, sections, defs):
    status = join(self.root, "co19.status")
    if exists(status):
      test.ReadConfigurationInto(status, sections, defs)

  def Contains(self, path, file):
    """ reimplemented for support '**' glob pattern """
    if len(path) > len(file):
      return 
    # ** matches to any number of directories, a/**/d matches a/b/c/d
    # paths like a/**/x/**/b not allowed
    patterns = [p.pattern for p in path]
    if '**' in patterns:
      idx = patterns.index('**')
      patterns[idx : idx] = ['*'] * (len(file) - len(path))
      path = [test.Pattern(p) for p in patterns]

    for i in xrange(len(path)):
      if not path[i].match(file[i]):
        return False
    return True

def GetConfiguration(context, root):
  return Co19TestConfiguration(context, root)
