#!/bin/bash
#
# hardware-contributions.sh
#
#    Copyright (C) 2013  Matti Lammi
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
# This script will produce information about my (lammi87) hardware 
# related contributions to h-node in human readable form. It will use 
# tools commonly found in GNU/Linux operating system distributions 
# and two source files to do this. Results will be saved to a file 
# and also displayed immediately.
#
# The source files are text files consisting on several one line 
# long entries of data. The data is copied from two of h-node's 
# lists of hardware related contributions. The first one [1] is a 
# list of actions carried out by all users. The second one [2] is a 
# different kind of list containing my actions alone. Both of these 
# lists can be accessed by anyone:
#
# [1] http://h-node.org/special/modifications/en
# [2] http://h-node.org/meet/hardware/en/lammi87
#
# The first list [1] is rather long, so I have included only the 
# entries starting from the day when I first started reporting 
# devices to h-node continuing to the present day in order to narrow 
# it down.
#
# I had to use two separate sources because neither one alone did not 
# include all the information I wanted. I also had to make sure that 
# the source files I made based on those lists contained only the 
# data I needed and nothing else. Anything extra like empty lines or 
# comments might have an effect to the results since this script will 
# search and count lines in various ways. 
#
# I have used many line breaks in this script so that I can keep the 
# layout clean when adding this script to my final thesis as an 
# appendix.
#
# Please note that the output of this script may not be 100% accurate.
# I think, however, that the results are accurate enough.
#
# SOURCE FILES
#
# [1] File name:            source-hardware-1
#     Date for first entry:  3 May   2012
#     Date for last entry:  26 March 2013
#
# [2] File name:            source-hardware-2
#     Date for first entry:  3 May   2012
#     Date for last entry:  26 March 2013
#


### Print instructions.
###
# "echo" program's -e option allows special characters like 
# \n to be implemented.
# \n = new line
# \t = tab
echo -e "H-node script: Hardware contributions\n"
echo -e "First argument:\t\t   Source file [1]"
echo -e "Second argument: \t   Source file [2]"
echo -e "Third argument:  \t   Output file\n"


### Quit if source file [1] is not given.
###
# Check if first argument is null.
#  ! = not
# -n = not null
if [ ! -n "$1" ]
then
echo "ERROR: No source [1] given. Read source code for more info."
exit 1
fi

# Check if source [1] does not exist.
#  ! = not
# -f = file exists
if [ ! -f "$1" ]
then
echo "ERROR: Source [1] not found. Read source code for more info."
exit 1
fi


### Quit if source file [2] is not given.
###
# Check if second argument is null.
#  ! = not
# -n = not null
if [ ! -n "$2" ]
then
echo "ERROR: No source [2] given. Read source code for more info."
exit 1
fi

# Check if source [2] does not exist.
#  ! = not
# -f = file exists
if [ ! -f "$2" ]
then
echo "ERROR: Source [2] not found. Read source code for more info."
exit 1
fi


### Quit if output file is not given.
###
# Check if third argument is null.
#  ! = not
# -n = not null
if [ ! -n "$3" ]
then
echo "ERROR: No output file given. Read source code for more info."
exit 1
fi


### Create output file.
###
# \n = new line
touch $3
echo -e "Output file created.\n\n"


### Define table format and lines
###
# I will print the data processed from the source files into easy 
# to read tables. I use "printf" instead of "echo" because it has 
# more options to format the output. I'll define a format for the 
# tables so I can easily use it to print several tables and keep 
# their formatting unanimous. The format is a 35 character long space 
# followed by eight character long space and a new line character. 
# I added the new line character because "printf" does not include 
# it to its output by default. The first space will align characters 
# printed into it to the left. The other space will align its content 
# to right.
# %s = string
# NN = reserved character space in %NNs
#  - = alignment to left
# \n = new line 
TABLE_FORMAT="%-40s%8s\n"

# I'll be using two kinds of "lines" of characters to make the 
# output look more readable. I'll define them here.
THICK_LINE="================================================="
THIN_LINE="-------------------------------------------------"


### Find out my hardware contributions
### 
# %s = string
# \n = new line
echo "Hardware contributions:" > $3
printf "%s\n\n" $THICK_LINE >> $3

# Find out how many new pieces of hardware I have added:
#
# Inspect all lines of the source file [1], get only those which 
# mention me and the word "inserted", count them and print the 
# result.
# NUM=$() = Run code defined in brackets and save result to NUM.
# Printf's syntax: printf <format> <argument>
NUM=$(cat $1 | grep lammi87 | grep inserted | wc -l)
printf $TABLE_FORMAT "New hardware inserted by me:" $NUM  >> $3

# Find out how many updates I have made to existing hardware 
# entries:
#
# Inspect all lines of the source file [1], get only those which 
# mention me and the word "updated", count them and print the 
# result.
# NUM=$() = Run code defined in brackets and save result to NUM.
# Printf's syntax: printf <format> <argument>
NUM=$(cat $1 | grep lammi87 | grep updated | wc -l)
printf $TABLE_FORMAT "Old hardware updated by me:" $NUM >> $3

# Find out how many hardware related contributions I have made 
# in total:
#
# Inspect all lines of the source file [1], get only those which 
# mention me, count them and print the result.
# Printf's syntax: printf <format> <argument>
# NUM=$() = Run code defined in brackets and save result to NUM.
#      %s = string
#      \n = new line
printf "%s\n" $THIN_LINE >> $3
NUM=$(cat $1 | grep lammi87 | wc -l)
printf $TABLE_FORMAT "All my contributions in total:" $NUM >> $3

# Find out how many hardware related contributions others 
# have made in total:
#
# Inspect all lines of the source file [1], get only those which 
# do not mention me, count them and print the result.
# NUM=$() = Run code defined in brackets and save result to NUM.
# Printf's syntax: printf <format> <argument>
NUM=$(cat $1 | grep -v lammi87 | wc -l)
printf $TABLE_FORMAT "Other's contributions in total:"  $NUM >> $3

# Find out how many hardware related contributions there 
# are in total:
#
# Inspect all lines of the source file [1], count them and print 
# the result.
# Printf's syntax: printf <format> <argument>
# NUM=$() = Run code defined in brackets and save result to NUM.
#      %s = string
#      \n = new line
printf "%s\n" $THIN_LINE >> $3
NUM=$(cat $1 | wc -l)
printf $TABLE_FORMAT "All contributions in total:"  $NUM >> $3


### Find out how many contributions I did per month.
###
# For each year, write an entry to output file. For each 
# month within that year, write an entry to output file and separately 
# count how many devices I have updated, inserted and contributed in 
# total (Each year is searched from the end of each line from the 
# source file [1] due to "$" after the YEAR variable). Also, count 
# total values for each three categories of contributions for each 
# year and print it.
# Printf's syntax: printf <format> <argument>
#      %s = string
#       - = alignment to left
#      \n = new line
#       \ = line break
# NUM=$() = Run code defined in brackets and save result to NUM.
# The "let" command enables arithmetic operations on variables.

# I'll be using another kind of table format for these month tables.
NEW_TABLE_FORMAT="%-18s%10s%10s%10s\n"

echo -e "\n\nMy contributions per month:" >> $3
printf "%s\n" $THICK_LINE >> $3

for YEAR in 2012 2013 
do

   printf "\n$NEW_TABLE_FORMAT" "Year: $YEAR" "Updated" \
          "Inserted" "Total" >> $3
   printf "%s\n" $THIN_LINE >> $3

      for MONTH in January February March April May June July August \
      September October November December
      do

         UPDATED=$(cat $1 | grep lammi87 | grep updated |\
                   grep $YEAR$ | grep $MONTH | wc -l)

         INSERTED=$(cat $1 | grep lammi87 | grep inserted |\
                    grep $YEAR$ | grep $MONTH | wc -l)

         TOTAL=$(cat $1 | grep lammi87 | grep $YEAR$ |\
                 grep $MONTH | wc -l)
         printf $NEW_TABLE_FORMAT $MONTH $UPDATED $INSERTED\
                $TOTAL >> $3
         let "UPDATED_IN_MONTH=$UPDATED_IN_MONTH+$UPDATED"
         let "INSERTED_IN_MONTH=$INSERTED_IN_MONTH+$INSERTED"
         let "TOTAL_IN_MONTH=$TOTAL_IN_MONTH+$TOTAL"

      done

   printf "%s\n" $THIN_LINE >> $3
   printf $NEW_TABLE_FORMAT "Total:" $UPDATED_IN_MONTH\
          $INSERTED_IN_MONTH $TOTAL_IN_MONTH >> $3

   UPDATED=0
   INSERTED=0
   TOTAL=0
   UPDATED_IN_MONTH=0
   INSERTED_IN_MONTH=0
   TOTAL_IN_MONTH=0

done


### Find out my contributions per hardware class per device.
###
# For each hardware class, get a device name from source file [2] and 
# count how many times it can be found in the source file [1] with my 
# user name in it. Then count how many update and insert type of 
# contributions I have made. Also count the total number of 
# contributions. Do this for each device in each hardware class. 
# Count total values of all contribution types. Print the results.
#
# sed is a line editor. I use it to cut out unnecessary stuff from 
# what I get from source file [2].
# Printf's syntax: printf <format> <argument>
#      \n = new line
#      %s = string
#       \ = line break
#      -n = not null (if statement)
# NUM=$() = Run code defined in brackets and save result to NUM.
echo -e "\n\nMy contributions per hardware class:" >> $3
printf "%s\n\n" $THICK_LINE >> $3

printf "$NEW_TABLE_FORMAT" "Class" "Updated" \
        "Inserted" "Total" >> $3
printf "%s\n" $THIN_LINE >> $3


for CLASS in notebook videocard soundcard wifi ethernet-card \
sd-card-reader webcam bluetooth acquisition-card 3G-card \
host-controller fingerprint-reader RAID-adapter modem printer \
scanner
do

   DEVICE_NAMES=$( sed -rn 's/^'"$CLASS"'\s+(.+)\s+/\1/p' "$2" )

   if [ -n "$DEVICE_NAMES" ]
   then
      
      UPDATED=$(grep -F "$DEVICE_NAMES" $1 | grep "lammi87" |\
          grep -c updated )
      INSERTED=$(grep -F "$DEVICE_NAMES" $1 | grep "lammi87" |\
          grep -c inserted )
      TOTAL=$(grep -F "$DEVICE_NAMES" $1 | grep -c "lammi87" )
   
   else

      UPDATED=0
      INSERTED=0
      TOTAL=0

   fi

   printf $NEW_TABLE_FORMAT $CLASS $UPDATED $INSERTED $TOTAL >> $3
   let "FINAL_UPDATED=$FINAL_UPDATED+$UPDATED"
   let "FINAL_INSERTED=$FINAL_INSERTED+$INSERTED"
   let "FINAL_TOTAL=$FINAL_TOTAL+$TOTAL"

done

printf "%s\n" $THIN_LINE >> $3
printf $NEW_TABLE_FORMAT "Total:" $FINAL_UPDATED\
       $FINAL_INSERTED $FINAL_TOTAL >> $3


### Show results.
###
cat $3


### Quit
###
# \n = new line
echo -e "\nAll done.\n"
exit 0
