#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cache import StemCache, PriceCache
import numpy
import os
import shutil

EPSILON = 0.001


def setup_module():
    global stemcache
    global pricematrix
    
    # remove cached files
    if os.path.isdir('cache'):
        shutil.rmtree('cache')
    
    stemcache = StemCache('cache', 'stemcache.dat', 5000)
    pricematrix = (
        numpy.array([
            [1,1,1,150,400,55],
            [1,1,1,150,430,55],
            [1,1,1,150,460,55],
            [1,1,1,150,490,55],
            [1,1,1,150,520,55],
            [1,1,1,150,550,55],
            [1,1,1,150,580,55],
            [1,1,1,150,610,55],
            [1,1,2,60,200,17],
            [1,1,2,60,230,17],
            [1,1,2,60,260,17],
            [1,1,2,60,290,17],
            [1,1,2,60,320,17],
            [1,1,2,60,350,17],
            [1,1,2,60,380,17],
            [1,1,2,60,410,17]], dtype=float),
        numpy.array([
            [1,2,1,150,400,55],
            [1,2,1,150,430,55],
            [1,2,1,150,460,55],
            [1,2,1,150,490,55],
            [1,2,1,150,520,55],
            [1,2,1,150,550,55],
            [1,2,1,150,580,55],
            [1,2,1,150,610,55],
            [1,2,2,60,200,17],
            [1,2,2,60,230,17],
            [1,2,2,60,260,17],
            [1,2,2,60,290,17],
            [1,2,2,60,320,17],
            [1,2,2,60,350,17],
            [1,2,2,60,380,17],
            [1,2,2,60,410,17]], dtype=float)
        )


def test_init():
    assert stemcache._divisor == None
    assert stemcache._log_reduction == None
    assert stemcache._max_lims_by_sp == {}
    assert stemcache._price_matrices == []

def test_update():
    # test updating with proper-sized trees (no too small trees)
    timber = {1: [123.45, 2345.67], 2: [67.890, 678.90]}
    for pm in (0, 1):
        for sp in (1, 2, 3):
            for d in numpy.arange(10, 50, 0.5):
                for h in numpy.arange(5, 30, 0.5):
                    sv = d * h / 3.0
                    stemcache.update(sv, timber, 0.3, sp, d, h,
                                     pricematrix[pm], 1, 0.10)
    print "stemcache size after 1st round: %d" % len(stemcache._cache)
    assert len(stemcache._cache) == 24000
    timber = {1: [123.45, 2345.67], 2: [67.890, 678.90]}
    for pm in (0, 1):
        for sp in (1, 2, 3):
            for d in numpy.arange(9, 51, 0.5):
                for h in numpy.arange(4, 31, 0.5):
                    sv = d * h / 3.0
                    stemcache.update(sv, timber, 0.3, sp, d, h,
                                     pricematrix[pm], 1, 0.10)
    print "stemcache size after 2st round: %d" % len(stemcache._cache)
    assert len(stemcache._cache) == 27216
    
    # test updating with too small trees
    for sp in (1, 2, 3):
        for d, h in ((1.0, 2.0), (1.3, 1.9), (4.5, 3.7), (2.3, 3.6)):
            stemcache.update(0.0, None, 0.3, sp, d, h, None, 1, 0.10, True)
    dl, hl = stemcache._max_lims_by_sp[1]
    print "limits for species %d: d=%0.1f, h=%0.1f" % (1, dl, hl)
    assert abs(stemcache._max_lims_by_sp[1][0] - 4.5) < EPSILON
    assert abs(stemcache._max_lims_by_sp[1][1] - 3.7) < EPSILON


def test_check():
    # test that given d-h combinations are found in the cache
    timber = {1: [0.0, 0.0], 2: [0.0, 0.0]}
    stemvol, buck = stemcache.check(timber, 0.3, 1, 10.0, 5.0, pricematrix[0],
                                    1, 0.10)
    print stemvol, buck
    assert abs(stemvol - 16.66666666666666) < EPSILON
    assert buck == False
    assert timber[1][0] == 123.45
    
    # another test...
    timber = {1: [0.0, 0.0], 2: [0.0, 0.0]}
    stemvol, buck = stemcache.check(timber, 0.3, 1, 45.5, 19.5, pricematrix[0],
                                    1, 0.10)
    print stemvol, buck
    assert abs(stemvol - 295.75) < EPSILON
    assert buck == False
    assert timber[1][0] == 123.45
    
    # test with combinations that are not found in the cache
    stemvol, buck = stemcache.check(timber, 0.3, 1, 7.0, 4.0, pricematrix[0],
                                    1, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, True)
    
    # another similar test...
    stemvol, buck = stemcache.check(timber, 0.3, 4, 45.5, 19.5, pricematrix[0],
                                    1, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, True)
    
    # another one...
    stemvol, buck = stemcache.check(timber, 0.3, 1, 45.5, 19.5, pricematrix[0],
                                    2, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, True)
    
    # and another one...
    stemvol, buck = stemcache.check(timber, 0.5, 1, 45.5, 19.5, pricematrix[0],
                                    1, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, True)
    
    # test with trees too small to buck
    stemvol, buck = stemcache.check(timber, 0.3, 1, 1.0, 2.0, None, 1, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, False)
    
    # another test...
    stemvol, buck = stemcache.check(timber, 0.3, 1, 4.5, 3.7, None, 1, 0.10)
    print stemvol, buck
    assert (stemvol, buck) == (0.0, False)
    
    