# Copyright (C) 2017 The Meme Factory, Inc.  http://www.meme.com/
#
# 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.

# Karl O. Pinc <kop@meme.com>

import pytest
import time

from enforcer import exceptions as ex
from enforcer import get_rules
from enforcer import header


# Helper functions

def mock_google_metainfo():
    return {'name': 'joe', 'id': '3'}


def mock_tagged_google_metainfo():
    return (get_rules.GOOGLE_SOURCE, mock_google_metainfo())


def mock_file_metainfo():
    return {'path': 'some/path',
            'mtime': 0}


#
# Test functions
#

# pretty_timestamp()

def test_pretty_timestamp_nodst(monkeypatch):
    '''A timestamp is produced when not in a DST zone'''
    monkeypatch.setattr(time, 'daylight', False)
    assert header.pretty_timestamp(time.time()) != ''


def test_pretty_timestamp_dst(monkeypatch):
    '''A timestamp is produced when in a DST zone'''
    monkeypatch.setattr(time, 'daylight', True)
    assert header.pretty_timestamp(time.time()) != ''


# rfc3339_to_timestamp()

def test_rfc3339_to_timestamp_value():
    '''Is a good timestamp produced?'''
    assert header.rfc3339_to_timestamp('1970-01-01T00:00:00.0Z') == 0


def test_rfc3339_to_timestamp_fail():
    '''Does a bad rfc3339 value raise an error?'''
    with pytest.raises(ex.Unrecognized3339TimeWarning):
        header.rfc3339_to_timestamp('bad')


# optional_append()

def test_optional_append_nokey():
    '''Nothing happens when the key is not in the dict'''
    lst = []
    header.optional_append(lst, {}, 'value', 'key')
    assert len(lst) == 0


def test_optional_append_key():
    '''The list gets longer when the key is in the dict'''
    lst = []
    header.optional_append(lst, {'key': 'something'}, 'value', 'key')
    assert len(lst) == 1


# build_google_modtime()

def test_build_google_modtime_none():
    '''With no mod time get an empty list'''
    assert len(header.build_google_modtime({})) == 0


def test_build_google_modtime_good():
    '''A good mod time produces a 1 element list'''
    assert len(header.build_google_modtime(
        {'modifiedTime': '1970-01-01T00:00:00.0Z'})) == 1


def test_build_google_modtime_bad(capsys):
    '''A bad mod time produces something on stdout and a 1 element list'''
    result = header.build_google_modtime({'modifiedTime': 'bad'})
    (out, err) = capsys.readouterr()

    assert len(result) == 1
    assert err != ''


# build_google_lastmod()

def test_build_google_lastmod_key():
    '''When there's a key a non-empty list is returned'''
    assert len(header.build_google_lastmod(
        {'lastModifyingUser': {'displayName': 'Joe',
                               'emailAddress': 'joe@example.com'}})) > 0


def test_build_google_lastmod_no_key():
    '''When there's no key a empty list is returned'''
    assert len(header.build_google_lastmod({})) == 0


# build_google_owners()

def test_build_google_owners_no_key():
    '''When there's no key an empty list is returned'''
    assert len(header.build_google_owners({})) == 0


def test_build_google_owners_one():
    '''When there's one owner you get one owner worth of output'''
    # Use a single element per owner, to make counting easy
    result = header.build_google_owners(
        {'owners': [{'displayName': 'joe'}]})
    assert len(result) == 1


def test_build_google_owners_two():
    '''When there's two owners you get two owners worth of output'''
    # Use a single element per owner, to make counting easy
    result = header.build_google_owners(
        {'owners': [{'displayName': 'joe'},
                    {'emailAddress': 'joe@example.com'}]})
    assert len(result) == 2


# build_googleinfo()

def test_build_googleinfo():
    '''Get something when given name and id?'''
    assert len(header.build_googleinfo(mock_google_metainfo())) > 0


# build_fileinfo()

def test_build_fileinfo():
    '''Get something?'''
    assert len(header.build_fileinfo(mock_file_metainfo())) > 0


# build_metainfo()

def test_build_metainfo_google():
    '''Supplying google metainfo returns a non-empty list'''
    assert len(header.build_metainfo(
        mock_tagged_google_metainfo())) > 1


def test_build_metainfo_file():
    '''Supplying file metainfo returns a non-empty list'''
    assert len(header.build_metainfo(
        (get_rules.FILE_SOURCE, mock_file_metainfo()))) > 1


# get_version()

def test_get_version():
    '''Returns a string with no newlines'''
    version = header.get_version()
    assert isinstance(version, str)
    assert version.count('\n') == 0


# build()

def test_build():
    '''Returns a non-empty list'''
    assert len(header.build(0, mock_tagged_google_metainfo())) > 1


# print_header()

def test_print_header(capsys):
    '''Prints on stdout but not stderr'''
    header.print_header(0, mock_tagged_google_metainfo())
    (out, err) = capsys.readouterr()
    assert out
    assert err == ''
