# Copyright (C) 2009 The Android Open Source Project
#
# 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.

"""Unittests for the git_config.py module."""

import os
import tempfile
import unittest

import git_config
import repo_trace


def fixture(*paths):
  """Return a path relative to test/fixtures.
  """
  return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)


class GitConfigReadOnlyTests(unittest.TestCase):
  """Read-only tests of the GitConfig class."""

  def setUp(self):
    """Create a GitConfig object using the test.gitconfig fixture.
    """

    self.tempdirobj = tempfile.TemporaryDirectory(prefix='repo_tests')
    repo_trace._TRACE_FILE = os.path.join(self.tempdirobj.name, 'TRACE_FILE_from_test')

    config_fixture = fixture('test.gitconfig')
    self.config = git_config.GitConfig(config_fixture)

  def tearDown(self):
    self.tempdirobj.cleanup()

  def test_GetString_with_empty_config_values(self):
    """
    Test config entries with no value.

    [section]
        empty

    """
    val = self.config.GetString('section.empty')
    self.assertEqual(val, None)

  def test_GetString_with_true_value(self):
    """
    Test config entries with a string value.

    [section]
        nonempty = true

    """
    val = self.config.GetString('section.nonempty')
    self.assertEqual(val, 'true')

  def test_GetString_from_missing_file(self):
    """
    Test missing config file
    """
    config_fixture = fixture('not.present.gitconfig')
    config = git_config.GitConfig(config_fixture)
    val = config.GetString('empty')
    self.assertEqual(val, None)

  def test_GetBoolean_undefined(self):
    """Test GetBoolean on key that doesn't exist."""
    self.assertIsNone(self.config.GetBoolean('section.missing'))

  def test_GetBoolean_invalid(self):
    """Test GetBoolean on invalid boolean value."""
    self.assertIsNone(self.config.GetBoolean('section.boolinvalid'))

  def test_GetBoolean_true(self):
    """Test GetBoolean on valid true boolean."""
    self.assertTrue(self.config.GetBoolean('section.booltrue'))

  def test_GetBoolean_false(self):
    """Test GetBoolean on valid false boolean."""
    self.assertFalse(self.config.GetBoolean('section.boolfalse'))

  def test_GetInt_undefined(self):
    """Test GetInt on key that doesn't exist."""
    self.assertIsNone(self.config.GetInt('section.missing'))

  def test_GetInt_invalid(self):
    """Test GetInt on invalid integer value."""
    self.assertIsNone(self.config.GetBoolean('section.intinvalid'))

  def test_GetInt_valid(self):
    """Test GetInt on valid integers."""
    TESTS = (
        ('inthex', 16),
        ('inthexk', 16384),
        ('int', 10),
        ('intk', 10240),
        ('intm', 10485760),
        ('intg', 10737418240),
    )
    for key, value in TESTS:
      self.assertEqual(value, self.config.GetInt('section.%s' % (key,)))


class GitConfigReadWriteTests(unittest.TestCase):
  """Read/write tests of the GitConfig class."""

  def setUp(self):
    self.tempdirobj = tempfile.TemporaryDirectory(prefix='repo_tests')
    repo_trace._TRACE_FILE = os.path.join(self.tempdirobj.name, 'TRACE_FILE_from_test')

    self.tmpfile = tempfile.NamedTemporaryFile()
    self.config = self.get_config()

  def tearDown(self):
    self.tempdirobj.cleanup()

  def get_config(self):
    """Get a new GitConfig instance."""
    return git_config.GitConfig(self.tmpfile.name)

  def test_SetString(self):
    """Test SetString behavior."""
    # Set a value.
    self.assertIsNone(self.config.GetString('foo.bar'))
    self.config.SetString('foo.bar', 'val')
    self.assertEqual('val', self.config.GetString('foo.bar'))

    # Make sure the value was actually written out.
    config = self.get_config()
    self.assertEqual('val', config.GetString('foo.bar'))

    # Update the value.
    self.config.SetString('foo.bar', 'valll')
    self.assertEqual('valll', self.config.GetString('foo.bar'))
    config = self.get_config()
    self.assertEqual('valll', config.GetString('foo.bar'))

    # Delete the value.
    self.config.SetString('foo.bar', None)
    self.assertIsNone(self.config.GetString('foo.bar'))
    config = self.get_config()
    self.assertIsNone(config.GetString('foo.bar'))

  def test_SetBoolean(self):
    """Test SetBoolean behavior."""
    # Set a true value.
    self.assertIsNone(self.config.GetBoolean('foo.bar'))
    for val in (True, 1):
      self.config.SetBoolean('foo.bar', val)
      self.assertTrue(self.config.GetBoolean('foo.bar'))

    # Make sure the value was actually written out.
    config = self.get_config()
    self.assertTrue(config.GetBoolean('foo.bar'))
    self.assertEqual('true', config.GetString('foo.bar'))

    # Set a false value.
    for val in (False, 0):
      self.config.SetBoolean('foo.bar', val)
      self.assertFalse(self.config.GetBoolean('foo.bar'))

    # Make sure the value was actually written out.
    config = self.get_config()
    self.assertFalse(config.GetBoolean('foo.bar'))
    self.assertEqual('false', config.GetString('foo.bar'))

    # Delete the value.
    self.config.SetBoolean('foo.bar', None)
    self.assertIsNone(self.config.GetBoolean('foo.bar'))
    config = self.get_config()
    self.assertIsNone(config.GetBoolean('foo.bar'))

  def test_GetSyncAnalysisStateData(self):
    """Test config entries with a sync state analysis data."""
    superproject_logging_data = {}
    superproject_logging_data['test'] = False
    options = type('options', (object,), {})()
    options.verbose = 'true'
    options.mp_update = 'false'
    TESTS = (
        ('superproject.test', 'false'),
        ('options.verbose', 'true'),
        ('options.mpupdate', 'false'),
        ('main.version', '1'),
    )
    self.config.UpdateSyncAnalysisState(options, superproject_logging_data)
    sync_data = self.config.GetSyncAnalysisStateData()
    for key, value in TESTS:
      self.assertEqual(sync_data[f'{git_config.SYNC_STATE_PREFIX}{key}'], value)
    self.assertTrue(sync_data[f'{git_config.SYNC_STATE_PREFIX}main.synctime'])
